Skip to content

Commit 1756004

Browse files
committed
fix(yarn): Fix up the error handling in getRemotePackageDetails()
Previously, calling `parseYarnInfo(process.stderr)` was useless, because it attempts to only parse a `PackageJson` instance from `stderr` which always fails, because `npm` does not output such data to `stderr`. However, in [1] the logging of errors obtained from `stderr` got (partially) removed. Fix this up by logging any errors found in `stderr` in case no `PackageJson` instance could be parsed from `stdout`. [1] ad9a363 Signed-off-by: Frank Viernau <[email protected]>
1 parent a8da7d4 commit 1756004

File tree

1 file changed

+24
-6
lines changed
  • plugins/package-managers/node/src/main/kotlin

1 file changed

+24
-6
lines changed

plugins/package-managers/node/src/main/kotlin/Yarn.kt

+24-6
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@ import kotlinx.serialization.encodeToString
2727
import kotlinx.serialization.json.Json
2828
import kotlinx.serialization.json.JsonObject
2929
import kotlinx.serialization.json.JsonPrimitive
30+
import kotlinx.serialization.json.contentOrNull
3031
import kotlinx.serialization.json.decodeToSequence
32+
import kotlinx.serialization.json.jsonPrimitive
33+
import org.apache.logging.log4j.kotlin.KotlinLogger
3134

3235
import org.apache.logging.log4j.kotlin.logger
3336

@@ -91,10 +94,8 @@ class Yarn(
9194

9295
val process = run(workingDir, "info", "--json", packageName)
9396

94-
return parseYarnInfo(process.stdout)?.also {
97+
return parseYarnInfo(process.stdout, process.stderr, logger())?.also {
9598
yarnInfoCache.write(packageName, Json.encodeToString(it))
96-
} ?: checkNotNull(parseYarnInfo(process.stderr)).also {
97-
logger.warn { "Error running '${process.commandLine}' in directory $workingDir: $it" }
9899
}
99100
}
100101
}
@@ -104,17 +105,34 @@ class Yarn(
104105
* metadata of the package that was queried. However, under certain circumstances, Yarn may return multiple JSON objects
105106
* separated by newlines; for instance, if the operation is retried due to network problems. This function filters for
106107
* the object with the data based on the _type_ field. Result is *null* if no matching object is found or the input is
107-
* not valid JSON.
108+
* not valid JSON. In that case any error found in [stderr] is logged with [logger].
108109
*
109110
* Note: The mentioned network issue can be reproduced by setting the network timeout to be very short via the command
110111
* line option '--network-timeout'.
111112
*/
112-
internal fun parseYarnInfo(stdout: String): PackageJson? =
113-
runCatching {
113+
internal fun Yarn.parseYarnInfo(stdout: String, stderr: String, logger: KotlinLogger? = null): PackageJson? {
114+
val packageJson = runCatching {
114115
stdout.byteInputStream().use { inputStream ->
115116
Json.decodeToSequence<JsonObject>(inputStream)
116117
.firstOrNull { (it["type"] as? JsonPrimitive)?.content == "inspect" }?.let {
117118
it["data"]?.let(::parsePackageJson)
118119
}
119120
}
120121
}.getOrNull()
122+
123+
if (packageJson == null) {
124+
runCatching {
125+
val errors = stdout.byteInputStream().use { inputStream ->
126+
Json.decodeToSequence<JsonObject>(inputStream).filter {
127+
(it["type"] as? JsonPrimitive)?.content == "error"
128+
}
129+
}.mapNotNull { it["data"]?.jsonPrimitive?.content }
130+
131+
errors.forEach { error ->
132+
logger?.warn { "Error parsing yarn info: $error." }
133+
}
134+
}
135+
}
136+
137+
return packageJson
138+
}

0 commit comments

Comments
 (0)