Skip to content

Commit e297b5a

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 7f762c9 commit e297b5a

File tree

2 files changed

+17
-9
lines changed

2 files changed

+17
-9
lines changed

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

+13-5
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
package org.ossreviewtoolkit.plugins.packagemanagers.node
2121

2222
import java.io.File
23+
import java.lang.invoke.MethodHandles
2324

2425
import kotlin.time.Duration.Companion.days
2526

@@ -29,8 +30,10 @@ import kotlinx.serialization.json.JsonElement
2930
import kotlinx.serialization.json.JsonObject
3031
import kotlinx.serialization.json.JsonPrimitive
3132
import kotlinx.serialization.json.decodeToSequence
33+
import kotlinx.serialization.json.jsonPrimitive
3234

3335
import org.apache.logging.log4j.kotlin.logger
36+
import org.apache.logging.log4j.kotlin.loggerOf
3437

3538
import org.ossreviewtoolkit.analyzer.AbstractPackageManagerFactory
3639
import org.ossreviewtoolkit.model.config.AnalyzerConfiguration
@@ -39,6 +42,7 @@ import org.ossreviewtoolkit.plugins.packagemanagers.node.utils.NodePackageManage
3942
import org.ossreviewtoolkit.plugins.packagemanagers.node.utils.NpmDetection
4043
import org.ossreviewtoolkit.utils.common.DiskCache
4144
import org.ossreviewtoolkit.utils.common.Os
45+
import org.ossreviewtoolkit.utils.common.alsoIfNull
4246
import org.ossreviewtoolkit.utils.common.mebibytes
4347
import org.ossreviewtoolkit.utils.ort.ortDataDirectory
4448

@@ -92,14 +96,14 @@ class Yarn(
9296

9397
val process = run(workingDir, "info", "--json", packageName)
9498

95-
return parseYarnInfo(process.stdout)?.also {
99+
return parseYarnInfo(process.stdout, process.stderr)?.also {
96100
yarnInfoCache.write(packageName, Json.encodeToString(it))
97-
} ?: checkNotNull(parseYarnInfo(process.stderr)).also {
98-
logger.warn { "Error running '${process.commandLine}' in directory $workingDir: $it" }
99101
}
100102
}
101103
}
102104

105+
private val logger = loggerOf(MethodHandles.lookup().lookupClass())
106+
103107
/**
104108
* Parse the given [stdout] of a Yarn _info_ command to a [PackageJson]. The output is typically a JSON object with the
105109
* metadata of the package that was queried. However, under certain circumstances, Yarn may return multiple JSON objects
@@ -110,8 +114,12 @@ class Yarn(
110114
* Note: The mentioned network issue can be reproduced by setting the network timeout to be very short via the command
111115
* line option '--network-timeout'.
112116
*/
113-
internal fun parseYarnInfo(stdout: String): PackageJson? =
114-
extractDataNodes(stdout, "inspect").firstOrNull()?.let(::parsePackageJson)
117+
internal fun parseYarnInfo(stdout: String, stderr: String): PackageJson? =
118+
extractDataNodes(stdout, "inspect").firstOrNull()?.let(::parsePackageJson).alsoIfNull {
119+
extractDataNodes(stderr, "error").forEach {
120+
logger.warn { "Error parsing yarn info: ${it.jsonPrimitive.content}." }
121+
}
122+
}
115123

116124
private fun extractDataNodes(output: String, type: String): Set<JsonElement> =
117125
runCatching {

plugins/package-managers/node/src/test/kotlin/YarnTest.kt

+4-4
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class YarnTest : WordSpec({
3333
"parse a valid JSON string" {
3434
val json = fileWithRetries.readLines()[3]
3535

36-
val packageJson = parseYarnInfo(json)
36+
val packageJson = parseYarnInfo(json, "")
3737

3838
packageJson?.homepage shouldBe "https://github.com/watson/bonjour/local"
3939
}
@@ -44,21 +44,21 @@ class YarnTest : WordSpec({
4444
Also not on any line.
4545
""".trimIndent()
4646

47-
parseYarnInfo(json) should beNull()
47+
parseYarnInfo(json, "") should beNull()
4848
}
4949

5050
"parse a JSON string with multiple objects" {
5151
val json = fileWithRetries.readText()
5252

53-
val packageJson = parseYarnInfo(json)
53+
val packageJson = parseYarnInfo(json, "")
5454

5555
packageJson?.homepage shouldBe "https://github.com/watson/bonjour/local"
5656
}
5757

5858
"handle a type property that is not a primitive" {
5959
val json = File("src/test/assets/yarn-package-data-with-wrong-type.txt").readText()
6060

61-
val packageJson = parseYarnInfo(json)
61+
val packageJson = parseYarnInfo(json, "")
6262

6363
packageJson?.homepage shouldBe "https://github.com/watson/bonjour/local"
6464
}

0 commit comments

Comments
 (0)