Skip to content

Commit

Permalink
[jssrc2cpg] Improve error handling even further (#5130)
Browse files Browse the repository at this point in the history
#5127 made `BabelJsonParser.readFile` a bit safer by simply
wrapping everything into a big try.

This PR changes that to:
 - separate Try blocks for type map loading, json loading, and parse result generation
 - forward exceptions from json loading and parse result generation to `AstCreationPass.runOnPart`, and
 - do a proper WARN logging of these exceptions
  • Loading branch information
max-leuthaeuser authored Nov 25, 2024
1 parent c73ff51 commit 141d8f0
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,37 @@ object BabelJsonParser {
fileLoc: Int
) extends BaseParserResult

def readFile(rootPath: Path, file: Path): Option[ParseResult] = {
Try {
val typeMapPath = Paths.get(file.toString.replace(".json", ".typemap"))
val typeMap = if (typeMapPath.toFile.exists()) {
val typeMapJsonContent = IOUtils.readEntireFile(typeMapPath)
val typeMapJson = ujson.read(typeMapJsonContent)
typeMapJson.obj.map { case (k, v) => k.toInt -> v.str }.toMap
} else {
Map.empty[Int, String]
}
val jsonContent = IOUtils.readEntireFile(file)
val json = ujson.read(jsonContent)
val filename = json("relativeName").str
val fullPath = Paths.get(rootPath.toString, filename)
val sourceFileContent = IOUtils.readEntireFile(fullPath)
val fileLoc = sourceFileContent.lines().count().toInt
ParseResult(filename, fullPath.toString, json, sourceFileContent, typeMap, fileLoc)
private def loadTypeMap(file: Path): Try[Map[Int, String]] = Try {
val typeMapPathString = file.toString.replaceAll("\\.[^.]*$", "") + ".typemap"
val typeMapPath = Paths.get(typeMapPathString)
if (typeMapPath.toFile.exists()) {
val typeMapJsonContent = IOUtils.readEntireFile(typeMapPath)
val typeMapJson = ujson.read(typeMapJsonContent)
typeMapJson.obj.map { case (k, v) => k.toInt -> v.str }.toMap
} else {
Map.empty
}
}.toOption
}

private def loadJson(file: Path): Try[Value] = Try {
val jsonContent = IOUtils.readEntireFile(file)
ujson.read(jsonContent)
}

private def generateParserResult(rootPath: Path, json: Value, typeMap: Map[Int, String]): Try[ParseResult] = Try {
val filename = json("relativeName").str
val fullPath = Paths.get(rootPath.toString, filename)
val sourceFileContent = IOUtils.readEntireFile(fullPath)
val fileLoc = sourceFileContent.lines().count().toInt
ParseResult(filename, fullPath.toString, json, sourceFileContent, typeMap, fileLoc)
}

def readFile(rootPath: Path, file: Path): Try[ParseResult] = {
val typeMap = loadTypeMap(file).getOrElse(Map.empty)
for {
json <- loadJson(file)
parseResult <- generateParserResult(rootPath, json, typeMap)
} yield parseResult
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class AstCreationPass(cpg: Cpg, astGenRunnerResult: AstGenRunnerResult, config:
val parseResultMaybe = BabelJsonParser.readFile(Paths.get(rootPath), Paths.get(jsonFilename))
val ((gotCpg, filename), duration) = TimeUtils.time {
parseResultMaybe match {
case Some(parseResult) =>
case Success(parseResult) =>
report.addReportInfo(parseResult.filename, parseResult.fileLoc, parsed = true)
Try {
val localDiff = new AstCreator(config, global, parseResult).createAst()
Expand All @@ -65,8 +65,10 @@ class AstCreationPass(cpg: Cpg, astGenRunnerResult: AstGenRunnerResult, config:
logger.debug(s"Generated a CPG for: '${parseResult.fullPath}'")
(true, parseResult.filename)
}
case None =>
(false, jsonFilename.replace(".json", ""))
case Failure(exception) =>
val pathOfFailedFile = jsonFilename.replaceAll("\\.[^.]*$", "")
logger.warn(s"Failed to read json parse result for: '$pathOfFailedFile'", exception)
(false, pathOfFailedFile)
}
}
report.updateReport(filename, cpg = gotCpg, duration)
Expand Down

0 comments on commit 141d8f0

Please sign in to comment.