Consolidated exceptions

This commit is contained in:
Felix Krause 2023-03-18 13:54:45 +01:00
parent f6e09ebb6a
commit 39444f6536
14 changed files with 124 additions and 143 deletions

View File

@ -2,11 +2,11 @@
"nodes": {
"nix-filter": {
"locked": {
"lastModified": 1661201956,
"narHash": "sha256-RizGJH/buaw9A2+fiBf9WnXYw4LZABB5kMAZIEE5/T8=",
"lastModified": 1678109515,
"narHash": "sha256-C2X+qC80K2C1TOYZT8nabgo05Dw2HST/pSn6s+n6BO8=",
"owner": "numtide",
"repo": "nix-filter",
"rev": "3b821578685d661a10b563cba30b1861eec05748",
"rev": "aa9ff6ce4a7f19af6415fb3721eaa513ea6c763c",
"type": "github"
},
"original": {
@ -40,11 +40,11 @@
},
"utils": {
"locked": {
"lastModified": 1659877975,
"narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=",
"lastModified": 1678901627,
"narHash": "sha256-U02riOqrKKzwjsxc/400XnElV+UtPUQWpANPlyazjH0=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0",
"rev": "93a2b84fc4b70d9e089d029deacc3583435c2ed6",
"type": "github"
},
"original": {

View File

@ -67,21 +67,18 @@ router nyRouter:
resultNode["code"] = %0
resultNode["output"] = %highlighted
msg = resultNode.pretty
except YamlParserError:
let e = (ref YamlParserError)(getCurrentException())
except YamlParserError as e:
resultNode["code"] = %1
resultNode["line"] = %e.mark.line
resultNode["column"] = %e.mark.column
resultNode["message"] = %e.msg
resultNode["detail"] = %e.lineContent
msg = resultNode.pretty
except YamlPresenterJsonError:
let e = getCurrentException()
except YamlPresenterJsonError as e:
resultNode["code"] = %2
resultNode["message"] = %e.msg
msg = resultNode.pretty
except:
let e = getCurrentException()
except CatchableError as e:
msg = "Name: " & $e.name & "\nMessage: " & e.msg &
"\nTrace:\n" & e.getStackTrace
retStatus = Http500

View File

@ -18,8 +18,8 @@ proc ensureEqual(yamlIn, jsonIn: string) =
assert yamlResult.len == 1
assert(jsonResult == yamlResult[0], "Expected: " & $jsonResult & ", got: " &
$yamlResult[0])
except YamlStreamError:
let e = (ref YamlParserError)(getCurrentException().parent)
except YamlStreamError as se:
let e = (ref YamlParserError)(se.parent)
echo "error occurred: " & e.msg
echo "line: ", e.mark.line, ", column: ", e.mark.column
echo e.lineContent

View File

@ -64,8 +64,7 @@ proc assertEquals(input: string, expected: varargs[TokenWithValue]) =
"Wrong indentation length at #" & $i & ": Expected " &
$expectedToken.indentation & ", got " & $lex.currentIndentation()
else: discard
except LexerError:
let e = (ref LexerError)(getCurrentException())
except LexerError as e:
echo "Error at line", e.line, ", column", e.column, ":", e.msg
echo e.lineContent
assert false

View File

@ -52,12 +52,11 @@ proc parserTest(path: string, errorExpected : bool): bool =
result = not errorExpected
if not result:
echo "Expected error, but parsed without error."
except:
except CatchableError as e:
result = errorExpected
if not result:
echoError("Caught an exception at event #" & $i &
" test was not successful")
let e = getCurrentException()
if e.parent of YamlParserError:
let pe = (ref YamlParserError)(e.parent)
echo "line ", pe.mark.line, ", column ", pe.mark.column, ": ", pe.msg

View File

@ -117,8 +117,7 @@ template expectConstructionError(li, co: int, message: string, body: typed) =
body
echo "Expected YamlConstructionError, but none was raised!"
fail()
except YamlConstructionError:
let e = (ref YamlConstructionError)(getCurrentException())
except YamlConstructionError as e:
doAssert li == e.mark.line, "Expected error line " & $li & ", was " & $e.mark.line
doAssert co == e.mark.column, "Expected error column " & $co & ", was " & $e.mark.column
doAssert message == e.msg, "Expected error message \n" & escape(message) &

View File

@ -237,8 +237,7 @@ proc loadMultiDom*(s: Stream | string): seq[YamlDocument]
result.add(compose(events, tagLib))
e = events.next()
yAssert(e.kind != yamlEndStream)
except YamlStreamError:
let ex = getCurrentException()
except YamlStreamError as ex:
if ex.parent of YamlParserError:
raise (ref YamlParserError)(ex.parent)
elif ex.parent of IOError:
@ -365,8 +364,7 @@ proc loadFlattened*[K](input: Stream | string, target: var K)
construct(stream, target)
e = stream.next()
yAssert(e.kind == yamlEndStream)
except YamlStreamError:
let e = (ref YamlStreamError)(getCurrentException())
except YamlStreamError as e:
if e.parent of IOError: raise (ref IOError)(e.parent)
if e.parent of OSError: raise (ref OSError)(e.parent)
elif e.parent of YamlParserError: raise (ref YamlParserError)(e.parent)

View File

@ -25,26 +25,7 @@ type
## only until the document goes out of scope (i.e. until
## ``yamlEndDocument`` is yielded).
issueWarnings: bool
State = proc(c: Context, e: var Event): bool {.gcSafe.}
Level = object
state: State
indentation: int
Context = ref object of YamlStream
handles: seq[tuple[handle, uriPrefix: string]]
issueWarnings: bool
lex: Lexer
levels: seq[Level]
keyCache: seq[Event]
keyCachePos: int
caching: bool
headerProps, inlineProps: Properties
headerStart, inlineStart: Mark
blockIndentation: int
YamlLoadingError* = object of ValueError
## Base class for all exceptions that may be raised during the process
## of loading a YAML character stream.
@ -53,7 +34,7 @@ type
## content of the line where the error was encountered. Includes a
## second line with a marker ``^`` at the position where the error
## was encountered.
YamlParserError* = object of YamlLoadingError
## A parser error is raised if the character stream that is parsed is
## not a valid YAML character stream. This stream cannot and will not be
@ -85,11 +66,30 @@ type
## Some elements in this list are vague. For a detailed description of a
## valid YAML character stream, see the YAML specification.
State = proc(c: Context, e: var Event): bool {.gcSafe, raises: [CatchableError].}
Level = object
state: State
indentation: int
Context = ref object of YamlStream
handles: seq[tuple[handle, uriPrefix: string]]
issueWarnings: bool
lex: Lexer
levels: seq[Level]
keyCache: seq[Event]
keyCachePos: int
caching: bool
headerProps, inlineProps: Properties
headerStart, inlineStart: Mark
blockIndentation: int
const defaultProperties = (yAnchorNone, yTagQuestionMark)
# parser states
{.push gcSafe, .}
{.push gcSafe, raises: [CatchableError], hint[XCannotRaiseY]: off.}
proc atStreamStart(c: Context, e: var Event): bool
proc atStreamEnd(c: Context, e : var Event): bool
proc beforeDoc(c: Context, e: var Event): bool
@ -155,7 +155,7 @@ proc resolveHandle(c: Context, handle: string): string {.raises: [].} =
proc init[T](c: Context, p: YamlParser, source: T) {.inline.} =
c.pushLevel(atStreamStart, -2)
c.nextImpl = proc(s: YamlStream, e: var Event): bool =
c.nextImpl = proc(s: YamlStream, e: var Event): bool {.raises: [CatchableError].} =
let c = Context(s)
return c.levels[^1].state(c, e)
c.lastTokenContextImpl = proc(s: YamlStream, lineContent: var string): bool =

View File

@ -273,10 +273,10 @@ proc writeDoubleQuoted(c: Context, scalar: string, indentation: int,
t.append(c)
curPos.inc()
t.append('"')
except:
except CatchableError as ce:
var e = newException(YamlPresenterOutputError,
"Error while writing to output stream")
e.parent = getCurrentException()
e.parent = ce
raise e
proc writeDoubleQuotedJson(c: Context, scalar: string)
@ -314,10 +314,10 @@ proc writeLiteral(c: Context, scalar: string, indentation, indentStep: int,
t.append(repeat(' ', indentation + indentStep))
if line.finish >= line.start:
t.append(scalar[line.start .. line.finish])
except:
except CatchableError as ce:
var e = newException(YamlPresenterOutputError,
"Error while writing to output stream")
e.parent = getCurrentException()
e.parent = ce
raise e
proc writeFolded(c: Context, scalar: string, indentation, indentStep: int,
@ -346,17 +346,17 @@ proc writeFolded(c: Context, scalar: string, indentation, indentStep: int,
curPos.inc()
t.append(scalar[word.start .. word.finish])
curPos += word.finish - word.start + 1
except:
except CatchableError as ce:
var e = newException(YamlPresenterOutputError,
"Error while writing to output stream")
e.parent = getCurrentException()
e.parent = ce
raise e
template safeWrite(c: Context, s: string or char) =
try: c.target.append(s)
except:
except CatchableError as ce:
var e = newException(YamlPresenterOutputError, "")
e.parent = getCurrentException()
e.parent = ce
raise e
proc startItem(c: var Context, indentation: int, isObject: bool,
@ -429,9 +429,9 @@ proc startItem(c: var Context, indentation: int, isObject: bool,
t.append(',' & newline)
t.append(repeat(' ', indentation))
of psBlockOnly: discard # can never happen
except:
except CatchableError as ce:
var e = newException(YamlPresenterOutputError, "")
e.parent = getCurrentException()
e.parent = ce
raise e
proc writeTagAndAnchor(c: Context, props: Properties) {.raises: [YamlPresenterOutputError].} =
@ -452,9 +452,9 @@ proc writeTagAndAnchor(c: Context, props: Properties) {.raises: [YamlPresenterOu
t.append("&")
t.append($props.anchor)
t.append(' ')
except:
except CatchableError as ce:
var e = newException(YamlPresenterOutputError, "")
e.parent = getCurrentException()
e.parent = ce
raise e
proc nextItem(c: var Deque, s: var YamlStream):
@ -503,9 +503,9 @@ proc doPresent(c: var Context, s: var YamlStream) =
else:
c.target.append("%TAG " & v.handle & ' ' & v.uriPrefix & newline)
c.target.append("--- ")
except:
except CatchableError as ce:
var e = newException(YamlPresenterOutputError, "")
e.parent = getCurrentException()
e.parent = ce
raise e
of yamlScalar:
if c.levels.len == 0:
@ -563,9 +563,9 @@ proc doPresent(c: var Context, s: var YamlStream) =
try:
c.target.append('*')
c.target.append($item.aliasTarget)
except:
except CatchableError as ce:
var e = newException(YamlPresenterOutputError, "")
e.parent = getCurrentException()
e.parent = ce
raise e
of yamlStartSeq:
var nextState: DumperState
@ -692,9 +692,9 @@ proc doPresent(c: var Context, s: var YamlStream) =
c.target.append(newline)
c.target.append(repeat(' ', indentation))
c.target.append(']')
except:
except CatchableError as ce:
var e = newException(YamlPresenterOutputError, "")
e.parent = getCurrentException()
e.parent = ce
raise e
if c.levels.len == 0 or c.state notin
[dBlockExplicitMapKey, dBlockMapValue,
@ -722,9 +722,9 @@ proc doPresent(c: var Context, s: var YamlStream) =
c.target.append(newline)
c.target.append(repeat(' ', indentation))
c.target.append('}')
except:
except CatchableError as ce:
var e = newException(YamlPresenterOutputError, "")
e.parent = getCurrentException()
e.parent = ce
raise e
if c.levels.len == 0 or c.state notin
[dBlockExplicitMapKey, dBlockMapValue,
@ -800,13 +800,13 @@ proc doTransform(c: var Context, input: Stream,
doPresent(c, bys)
else:
doPresent(c, events)
except YamlStreamError:
var e = getCurrentException()
while e.parent of YamlStreamError: e = e.parent
if e.parent of IOError: raise (ref IOError)(e.parent)
elif e.parent of OSError: raise (ref OSError)(e.parent)
elif e.parent of YamlParserError: raise (ref YamlParserError)(e.parent)
else: internalError("Unexpected exception: " & e.parent.repr)
except YamlStreamError as e:
var curE: ref Exception = e
while curE.parent of YamlStreamError: curE = curE.parent
if curE.parent of IOError: raise (ref IOError)(curE.parent)
elif curE.parent of OSError: raise (ref OSError)(curE.parent)
elif curE.parent of YamlParserError: raise (ref YamlParserError)(curE.parent)
else: internalError("Unexpected exception: " & curE.parent.repr)
proc genInput(input: Stream): Stream = input
proc genInput(input: string): Stream = newStringStream(input)

View File

@ -21,7 +21,7 @@ template internalError*(s: string) =
echo "… stacktrace [", exc.name, ": ", exc.msg, "]"
echo getStackTrace(exc)
exc = exc.parent
except: discard
except CatchableError: discard
echo "[NimYAML] Please report this bug."
quit 1
@ -39,7 +39,7 @@ template yAssert*(e: typed) =
if not isNil(exc.parent):
echo "Internal stacktrace:"
echo getStackTrace(exc.parent)
except: discard
except CatchableError: discard
echo "[NimYAML] Please report this bug."
quit 1

View File

@ -100,19 +100,17 @@ proc advance(lex: var Lexer, step: int = 1) {.inline.} =
template lexCR(lex: var Lexer) =
try: lex.source.bufpos = lex.source.handleCR(lex.source.bufpos - 1)
except:
var e = lex.generateError("Encountered stream error: " &
getCurrentExceptionMsg())
e.parent = getCurrentException()
except CatchableError as ce:
var e = lex.generateError("Encountered stream error: " & ce.msg)
e.parent = ce
raise e
lex.advance()
template lexLF(lex: var Lexer) =
try: lex.source.bufpos = lex.source.handleLF(lex.source.bufpos - 1)
except:
var e = generateError(lex, "Encountered stream error: " &
getCurrentExceptionMsg())
e.parent = getCurrentException()
except CatchableError as ce:
var e = generateError(lex, "Encountered stream error: " & ce.msg)
e.parent = ce
raise e
lex.advance()
@ -768,7 +766,7 @@ proc init*(lex: var Lexer, source: Stream) {.raises: [IOError, OSError].} =
proc init*(lex: var Lexer, source: string) {.raises: [].} =
try:
lex.source.open(newStringStream(source))
except:
except CatchableError:
discard # can never happen with StringStream
lex.basicInit()

View File

@ -138,12 +138,12 @@ template constructScalarItem*(s: var YamlStream, i: untyped,
raise constructionError(s, i.startPos, "Expected scalar")
try: content
except YamlConstructionError as e: raise e
except Exception:
var e = constructionError(s, i.startPos,
except CatchableError as e:
var ce = constructionError(s, i.startPos,
"Cannot construct to " & name(t) & ": " & item.scalarContent &
"; error: " & getCurrentExceptionMsg())
e.parent = getCurrentException()
raise e
"; error: " & e.msg)
ce.parent = e
raise ce
proc yamlTag*(T: typedesc[string]): Tag {.inline, noSideEffect, raises: [].} =
yTagString
@ -233,9 +233,9 @@ proc representObject*(value: int, tagStyle: TagStyle,
# currently, sizeof(int) is at least sizeof(int32).
try: c.put(scalarEvent($int32(value), tag, yAnchorNone))
except RangeDefect:
var e = newException(YamlSerializationError, getCurrentExceptionMsg())
e.parent = getCurrentException()
except RangeDefect as rd:
var e = newException(YamlSerializationError, rd.msg)
e.parent = rd
raise e
when defined(JS):
@ -284,9 +284,9 @@ proc representObject*(value: uint, ts: TagStyle, c: SerializationContext,
## represent an unsigned integer of architecture-defined length by casting it
## to int32. on 64-bit systems, this may cause a RangeDefect.
try: c.put(scalarEvent($uint32(value), tag, yAnchorNone))
except RangeDefect:
var e = newException(YamlSerializationError, getCurrentExceptionMsg())
e.parent = getCurrentException()
except RangeDefect as rd:
var e = newException(YamlSerializationError, rd.msg)
e.parent = rd
raise e
proc constructObject*[T: float|float32|float64](
@ -1030,10 +1030,10 @@ proc constructObject*[O: enum](s: var YamlStream, c: ConstructionContext,
if e.kind != yamlScalar:
raise s.constructionError(e.startPos, "Expected scalar, got " & $e.kind)
try: result = parseEnum[O](e.scalarContent)
except ValueError:
except ValueError as ve:
var ex = s.constructionError(e.startPos, "Cannot parse '" &
escape(e.scalarContent) & "' as " & type(O).name)
ex.parent = getCurrentException()
ex.parent = ve
raise ex
proc representObject*[O: enum](value: O, ts: TagStyle,
@ -1264,13 +1264,11 @@ proc constructChild*[O](s: var YamlStream, c: ConstructionContext,
else: internalError("Unexpected event kind: " & $e.kind)
s.peek = e
try: constructChild(s, c, result[])
except YamlConstructionError as e:
raise e
except YamlStreamError as e:
raise e
except Exception:
var e = newException(YamlStreamError, getCurrentExceptionMsg())
e.parent = getCurrentException()
except YamlConstructionError as e: raise e
except YamlStreamError as e: raise e
except CatchableError as ce:
var e = newException(YamlStreamError, ce.msg)
e.parent = ce
raise e
proc representChild*(value: string, ts: TagStyle, c: SerializationContext) =
@ -1362,14 +1360,12 @@ proc construct*[T](s: var YamlStream, target: var T)
constructChild(s, context, target)
e = s.next()
yAssert(e.kind == yamlEndDoc)
except YamlConstructionError:
raise (ref YamlConstructionError)(getCurrentException())
except YamlStreamError:
raise (ref YamlStreamError)(getCurrentException())
except Exception:
except YamlConstructionError as e: raise e
except YamlStreamError as e: raise e
except CatchableError as ce:
# may occur while calling s()
var ex = newException(YamlStreamError, "")
ex.parent = getCurrentException()
var ex = newException(YamlStreamError, "error occurred while constructing")
ex.parent = ce
raise ex
proc load*[K](input: Stream | string, target: var K)
@ -1390,8 +1386,7 @@ proc load*[K](input: Stream | string, target: var K)
mark: e.startPos, msg: "stream contains multiple documents")
discard events.getLastTokenContext(ex.lineContent)
raise ex
except YamlStreamError:
let e = (ref YamlStreamError)(getCurrentException())
except YamlStreamError as e:
if e.parent of IOError: raise (ref IOError)(e.parent)
if e.parent of OSError: raise (ref OSError)(e.parent)
elif e.parent of YamlParserError: raise (ref YamlParserError)(e.parent)
@ -1415,12 +1410,10 @@ proc loadMultiDoc*[K](input: Stream | string, target: var seq[K]) =
target.add(item)
e = events.next()
yAssert(e.kind == yamlEndStream)
except YamlConstructionError:
var e = (ref YamlConstructionError)(getCurrentException())
except YamlConstructionError as e:
discard events.getLastTokenContext(e.lineContent)
raise e
except YamlStreamError:
let e = (ref YamlStreamError)(getCurrentException())
except YamlStreamError as e:
if e.parent of IOError: raise (ref IOError)(e.parent)
elif e.parent of OSError: raise (ref OSError)(e.parent)
elif e.parent of YamlParserError: raise (ref YamlParserError)(e.parent)
@ -1463,9 +1456,10 @@ proc dump*[K](value: K, target: Stream, tagStyle: TagStyle = tsRootOnly,
if options.style == psCanonical: tsAll else: tagStyle,
if options.style == psJson: asNone else: anchorStyle, handles)
try: present(events, target, options)
except YamlStreamError:
internalError("Unexpected exception: " & $getCurrentException().name)
except YamlStreamError as e:
internalError("Unexpected exception: " & $e.name)
{.push hint[XCannotRaiseY]: off.}
proc dump*[K](value: K, tagStyle: TagStyle = tsRootOnly,
anchorStyle: AnchorStyle = asTidy,
options: PresentationOptions = defaultPresentationOptions,
@ -1479,5 +1473,6 @@ proc dump*[K](value: K, tagStyle: TagStyle = tsRootOnly,
if options.style == psCanonical: tsAll else: tagStyle,
if options.style == psJson: asNone else: anchorStyle, handles)
try: result = present(events, options)
except YamlStreamError:
internalError("Unexpected exception: " & $getCurrentException().name)
except YamlStreamError as e:
internalError("Unexpected exception: " & $e.name)
{.pop.}

View File

@ -18,6 +18,11 @@ when defined(nimNoNil):
{.experimental: "notnil".}
type
YamlStreamError* = object of ValueError
## Exception that may be raised by a ``YamlStream`` when the underlying
## backend raises an exception. The error that has occurred is
## available from ``parent``.
YamlStream* = ref object of RootObj ## \
## A ``YamlStream`` is an iterator-like object that yields a
## well-formed stream of ``YamlStreamEvents``. Well-formed means that
@ -31,17 +36,12 @@ type
## and is not required to check for it. The procs in this module will
## always yield a well-formed ``YamlStream`` and expect it to be
## well-formed if they take it as input parameter.
nextImpl*: proc(s: YamlStream, e: var Event): bool {.gcSafe.}
nextImpl*: proc(s: YamlStream, e: var Event): bool {.gcSafe, raises: [CatchableError] .}
lastTokenContextImpl*:
proc(s: YamlStream, lineContent: var string): bool {.raises: [].}
peeked: bool
cached: Event
YamlStreamError* = object of ValueError
## Exception that may be raised by a ``YamlStream`` when the underlying
## backend raises an exception. The error that has occurred is
## available from ``parent``.
proc noLastContext(s: YamlStream, lineContent: var string): bool {.raises: [].} =
result = false
@ -55,15 +55,15 @@ proc basicInit*(s: YamlStream, lastTokenContextImpl:
when not defined(JS):
type IteratorYamlStream = ref object of YamlStream
backend: iterator(): Event {.gcSafe.}
backend: iterator(): Event {.gcSafe, raises: [CatchableError].}
proc initYamlStream*(backend: iterator(): Event {.gcSafe.}): YamlStream
proc initYamlStream*(backend: iterator(): Event {.gcSafe, raises: [CatchableError].}): YamlStream
{.raises: [].} =
## Creates a new ``YamlStream`` that uses the given iterator as backend.
result = new(IteratorYamlStream)
result.basicInit()
IteratorYamlStream(result).backend = backend
result.nextImpl = proc(s: YamlStream, e: var Event): bool {.gcSafe.} =
result.nextImpl = proc(s: YamlStream, e: var Event): bool {.gcSafe, raises: [CatchableError].} =
e = IteratorYamlStream(s).backend()
result = true
@ -97,12 +97,10 @@ proc next*(s: YamlStream): Event {.raises: [YamlStreamError], gcSafe.} =
try:
while true:
if s.nextImpl(s, result): break
except YamlStreamError:
raise (ref YamlStreamError)(getCurrentException())
except Exception:
let cur = getCurrentException()
var e = newException(YamlStreamError, cur.msg)
e.parent = cur
except YamlStreamError as e: raise e
except CatchableError as ce:
var e = newException(YamlStreamError, ce.msg)
e.parent = ce
raise e
proc peek*(s: YamlStream): lent Event {.raises: [YamlStreamError].} =

View File

@ -70,9 +70,9 @@ proc jsonFromScalar(content: sink string, tag: Tag): JsonNode
result.str = content
else:
shallowCopy(result.str, content)
except ValueError:
except ValueError as ve:
var e = newException(YamlConstructionError, "Cannot parse numeric value")
e.parent = getCurrentException()
e.parent = ve
raise e
proc constructJson*(s: var YamlStream): seq[JsonNode]
@ -190,8 +190,7 @@ when not defined(JS):
var events = parser.parse(s)
try:
return constructJson(events)
except YamlStreamError:
let e = getCurrentException()
except YamlStreamError as e:
if e.parent of IOError:
raise (ref IOError)(e.parent)
elif e.parent of OSError:
@ -209,8 +208,7 @@ proc loadToJson*(str: string): seq[JsonNode]
parser.init()
var events = parser.parse(str)
try: return constructJson(events)
except YamlStreamError:
let e = getCurrentException()
except YamlStreamError as e:
if e.parent of YamlParserError:
raise (ref YamlParserError)(e.parent)
else: internalError("Unexpected exception: " & e.parent.repr)