From ad7c1ab9adc9ed3a4df771f862f76f377b55692b Mon Sep 17 00:00:00 2001 From: Nimaoth Date: Sun, 7 Jan 2024 17:13:20 +0100 Subject: [PATCH] fixed crash when nim std path can't be found --- src/app.nim | 9 ++++--- src/scripting/scripting_nim.nim | 46 +++++++++++++++++++-------------- 2 files changed, 33 insertions(+), 22 deletions(-) diff --git a/src/app.nim b/src/app.nim index 847f26df..9e4005d5 100644 --- a/src/app.nim +++ b/src/app.nim @@ -591,7 +591,7 @@ proc setTheme*(self: App, path: string) = self.platform.requestRender() when not defined(js): - var createScriptContext: proc(filepath: string, searchPaths: seq[string]): Future[ScriptContext] = nil + var createScriptContext: proc(filepath: string, searchPaths: seq[string]): Future[Option[ScriptContext]] = nil proc getCommandLineTextEditor*(self: App): TextDocumentEditor = self.commandLineTextEditor.TextDocumentEditor @@ -625,7 +625,10 @@ proc initScripting(self: App) {.async.} = path = fs.getApplicationFilePath(rest) when not defined(js): - self.scriptContext = await createScriptContext("./config/absytree_config.nim", searchPaths) + if createScriptContext("./config/absytree_config.nim", searchPaths).await.getSome(scriptContext): + self.scriptContext = scriptContext + else: + log lvlError, "Failed to create nim script context" withScriptContext self, self.scriptContext: log(lvlInfo, fmt"init nim script config") @@ -2022,7 +2025,7 @@ template createNimScriptContextConstructorAndGenerateBindings*(): untyped = createScriptContextConstructor(addins) - proc createScriptContextImpl(filepath: string, searchPaths: seq[string]): Future[ScriptContext] = createScriptContextNim(filepath, searchPaths) + proc createScriptContextImpl(filepath: string, searchPaths: seq[string]): Future[Option[ScriptContext]] = createScriptContextNim(filepath, searchPaths) createScriptContext = createScriptContextImpl createEditorWasmImportConstructor() \ No newline at end of file diff --git a/src/scripting/scripting_nim.nim b/src/scripting/scripting_nim.nim index 2c96ce77..78e5fd87 100644 --- a/src/scripting/scripting_nim.nim +++ b/src/scripting/scripting_nim.nim @@ -204,37 +204,45 @@ proc mySafeLoadScriptWithState*(self: ScriptContextNim, modules: seq[string]) {. if state.getSome(state): inter.loadState(state) -proc myFindNimStdLib(): string = +proc myFindNimStdLib(): Option[string] = ## Tries to find a path to a valid "system.nim" file. ## Returns "" on failure. let customNimStdLib = getAppDir() / "scripting" / "nim" / "lib" if dirExists(customNimStdLib): log lvlInfo, fmt"Using custom nim std lib '{customNimStdLib}'" - return customNimStdLib + return customNimStdLib.some try: log lvlInfo, "Searching for nim std lib directory using 'nim --verbosity:0 dump --dump.format:json .'" let nimdump = execProcess("nim", ".", ["--verbosity:0", "dump", "--dump.format:json", "."], options={poUsePath, poDaemon}) - let nimdumpJson = nimdump.parseJson() - return nimdumpJson["libpath"].getStr "" + let nimdumpJson = try: + nimdump.parseJson() + except: + log lvlError, &"Failed to parse output of nim dump: {getCurrentExceptionMsg()}\n{nimdump}" + return string.none + + return nimdumpJson["libpath"].getStr("").some except OSError, ValueError: - log lvlError, fmt"Failed to find nim std path using nim dump: {getCurrentExceptionMsg()}" - return "" - -proc newScriptContext*(path: string, apiModule: string, addins: VMAddins, postCodeAdditions: string, searchPaths: seq[string]): Future[ScriptContextNim] {.async.} = - new result - result.script = NimScriptPath(path) - result.apiModule = apiModule - result.addins = addins - result.postCodeAdditions = postCodeAdditions - result.searchPaths = searchPaths - - result.stdPath = myFindNimStdLib() - if result.stdPath == "": + log lvlError, &"Failed to find nim std path using nim dump: {getCurrentExceptionMsg()}" + return string.none + +proc newScriptContext*(path: string, apiModule: string, addins: VMAddins, postCodeAdditions: string, searchPaths: seq[string]): Future[Option[ScriptContext]] {.async.} = + let stdPath = myFindNimStdLib().getOr: log lvlError, "Failed to find nim std path" + return ScriptContext.none + + let res = ScriptContextNim() + res.script = NimScriptPath(path) + res.apiModule = apiModule + res.addins = addins + res.postCodeAdditions = postCodeAdditions + res.searchPaths = searchPaths + res.stdPath = stdPath + + log lvlInfo, fmt"Creating new script context (search paths: {searchPaths}, std path: {res.stdPath})" - log lvlInfo, fmt"Creating new script context (search paths: {searchPaths}, std path: {result.stdPath})" + return res.ScriptContext.some method init*(self: ScriptContextNim, path: string): Future[void] {.async.} = self.state = Initializing @@ -294,7 +302,7 @@ proc generateScriptingApi*(addins: VMAddins) {.compileTime.} = generateScriptingApiPerModule() template createScriptContextConstructor*(addins: untyped): untyped = - proc createScriptContextNim(filepath: string, searchPaths: seq[string]): Future[ScriptContext] {.async.} = + proc createScriptContextNim(filepath: string, searchPaths: seq[string]): Future[Option[ScriptContext]] {.async.} = return await newScriptContext(filepath, "absytree_internal", addins, "include absytree_runtime_impl", searchPaths) macro invoke*(self: ScriptContext; pName: untyped;