I came across an unintuitive behavior when writing a macro, where a JsonParsingError thrown by marshal.to was not catchable, even though it was placed in a try...except block.
Code
import marshal
macro caught() =
try:
raise newException(Exception, "blah")
except:
echo "oops"
macro uncatchable() =
try:
let x = to[seq[string]]("yadayada")
discard x
except:
echo "oops"
# oops
caught()
# parsejson.nim(515) raiseParseErr
# Error: unhandled exception: unknown file(1, 8) Error: '[' expected for a seq expected [JsonParsingError]
uncatchable()
nim -v Nim Compiler Version 1.6.8 [Linux: amd64] Compiled at 2022-10-05 Copyright (c) 2006-2021 by Andreas Rumpf git hash: c9f46ca8c9eeca8b5f68591b1abe14b962f80a4c active boot switches: -d:release
Compile with nim c to get the output.
The JsonParseError seems to be defined here which is a ValueError, so I'd expect it to be catchable.
compiler/vmops.nim:
registerCallback c, "stdlib.marshal.toVM", proc(a: VmArgs) =
let typ = a.getNode(0).typ
case typ.kind
of tyInt..tyInt64, tyUInt..tyUInt64:
setResult(a, loadAny(a.getString(1), typ, c.cache, c.config, c.idgen).intVal)
of tyFloat..tyFloat128:
setResult(a, loadAny(a.getString(1), typ, c.cache, c.config, c.idgen).floatVal)
else:
setResult(a, loadAny(a.getString(1), typ, c.cache, c.config, c.idgen))
registerCallback c, "stdlib.marshal.loadVM", proc(a: VmArgs) =
let typ = a.getNode(0).typ
let p = a.getReg(1)
var res: string
storeAny(res, typ, regToNode(p[]), c.config)
setResult(a, res)
Needs some error handling I suppose but when I designed this I thought, "who wants the compilation to continue after illformed JSon that you try to eval at compile time?" ;-)
Which of these alternatives run at compile time? And at comparable compile time speed?
I know it's unfair but what is linked into the VM as native code runs much faster.
Re: "who wants the compilation to continue after illformed JSon that you try to eval at compile time?"
What I was trying to do is use staticExec to run some other process, then parse the output string. The compilation definitely should fail when the parse fails, but I thought it would be nice to be able catch exception and give a more meaningful error msg to the user.