Skip to content

Commit 5f0b70d

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 `yarn` 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 f3889be commit 5f0b70d

File tree

2 files changed

+17
-10
lines changed

2 files changed

+17
-10
lines changed

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

+13-6
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,9 @@ 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

33-
import org.apache.logging.log4j.kotlin.logger
35+
import org.apache.logging.log4j.kotlin.loggerOf
3436

3537
import org.ossreviewtoolkit.analyzer.AbstractPackageManagerFactory
3638
import org.ossreviewtoolkit.model.config.AnalyzerConfiguration
@@ -39,6 +41,7 @@ import org.ossreviewtoolkit.plugins.packagemanagers.node.utils.NodePackageManage
3941
import org.ossreviewtoolkit.plugins.packagemanagers.node.utils.NpmDetection
4042
import org.ossreviewtoolkit.utils.common.DiskCache
4143
import org.ossreviewtoolkit.utils.common.Os
44+
import org.ossreviewtoolkit.utils.common.alsoIfNull
4245
import org.ossreviewtoolkit.utils.common.mebibytes
4346
import org.ossreviewtoolkit.utils.ort.ortDataDirectory
4447

@@ -92,14 +95,14 @@ class Yarn(
9295

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

95-
return parseYarnInfo(process.stdout)?.also {
98+
return parseYarnInfo(process.stdout, process.stderr)?.also {
9699
yarnInfoCache.write(packageName, Json.encodeToString(it))
97-
} ?: checkNotNull(parseYarnInfo(process.stderr)).also {
98-
logger.warn { "Error running '${process.commandLine}' in directory $workingDir: $it" }
99100
}
100101
}
101102
}
102103

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

116123
private fun extractDataNodes(output: String, type: String): Set<JsonElement> =
117124
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)