Simplify async traceback processing.
This commit is contained in:
parent
3593a4bdd1
commit
7e6dc3679a
2 changed files with 58 additions and 71 deletions
|
|
@ -217,44 +217,6 @@ proc `callback=`*[T](future: Future[T],
|
||||||
## If future has already completed then ``cb`` will be called immediately.
|
## If future has already completed then ``cb`` will be called immediately.
|
||||||
future.callback = proc () = cb(future)
|
future.callback = proc () = cb(future)
|
||||||
|
|
||||||
proc mergeEntries(entries: seq[StackTraceEntry]): seq[StackTraceEntry] =
|
|
||||||
## Merges stack trace entries containing re-raise entries into one
|
|
||||||
## continuous stack trace.
|
|
||||||
result = @[]
|
|
||||||
var i = 0
|
|
||||||
while i < entries.len:
|
|
||||||
var entry = entries[i]
|
|
||||||
|
|
||||||
if entry.procName.isNil:
|
|
||||||
# Start of a re-raise traceback which may contain more info.
|
|
||||||
# Find where the re-raised traceback ends.
|
|
||||||
assert entry.line == -10 # Signifies start of re-raise block.
|
|
||||||
var reRaiseEnd = i+1
|
|
||||||
while reRaiseEnd < entries.len and not entries[reRaiseEnd].procName.isNil:
|
|
||||||
reRaiseEnd.inc()
|
|
||||||
assert entries[reRaiseEnd].procName.isNil
|
|
||||||
assert entries[reRaiseEnd].line == -100 # Signifies end of re-raise block.
|
|
||||||
|
|
||||||
# either the nested block is new, then we insert it, or we discard it
|
|
||||||
# completely. 'diff' is the wrong idea here.
|
|
||||||
var last = result.len-1
|
|
||||||
var e = reRaiseEnd-1
|
|
||||||
var newBlock = false
|
|
||||||
while last >= 0 and e >= i+1:
|
|
||||||
if result[last] != entries[e]:
|
|
||||||
newBlock = true
|
|
||||||
break
|
|
||||||
dec e
|
|
||||||
dec last
|
|
||||||
|
|
||||||
if newBlock:
|
|
||||||
for j in i+1 ..< reRaiseEnd: result.add entries[j]
|
|
||||||
|
|
||||||
i = reRaiseEnd+1
|
|
||||||
else:
|
|
||||||
result.add(entry)
|
|
||||||
i.inc
|
|
||||||
|
|
||||||
proc getHint(entry: StackTraceEntry): string =
|
proc getHint(entry: StackTraceEntry): string =
|
||||||
## We try to provide some hints about stack trace entries that the user
|
## We try to provide some hints about stack trace entries that the user
|
||||||
## may not be familiar with, in particular calls inside the stdlib.
|
## may not be familiar with, in particular calls inside the stdlib.
|
||||||
|
|
@ -275,22 +237,33 @@ proc `$`*(entries: seq[StackTraceEntry]): string =
|
||||||
# Find longest filename & line number combo for alignment purposes.
|
# Find longest filename & line number combo for alignment purposes.
|
||||||
var longestLeft = 0
|
var longestLeft = 0
|
||||||
for entry in entries:
|
for entry in entries:
|
||||||
|
if entry.procName.isNil: continue
|
||||||
|
|
||||||
let left = $entry.filename & $entry.line
|
let left = $entry.filename & $entry.line
|
||||||
if left.len > longestLeft:
|
if left.len > longestLeft:
|
||||||
longestLeft = left.len
|
longestLeft = left.len
|
||||||
|
|
||||||
const indent = spaces(2)
|
var indent = 2
|
||||||
# Format the entries.
|
# Format the entries.
|
||||||
for entry in entries:
|
for entry in entries:
|
||||||
|
if entry.procName.isNil:
|
||||||
|
if entry.line == -10:
|
||||||
|
result.add(spaces(indent) & "#[\n")
|
||||||
|
indent.inc(2)
|
||||||
|
else:
|
||||||
|
indent.dec(2)
|
||||||
|
result.add(spaces(indent)& "]#\n")
|
||||||
|
continue
|
||||||
|
|
||||||
let left = "$#($#)" % [$entry.filename, $entry.line]
|
let left = "$#($#)" % [$entry.filename, $entry.line]
|
||||||
result.add((indent & "$#$# $#\n") % [
|
result.add((spaces(indent) & "$#$# $#\n") % [
|
||||||
left,
|
left,
|
||||||
spaces(longestLeft - left.len + 2),
|
spaces(longestLeft - left.len + 2),
|
||||||
$entry.procName
|
$entry.procName
|
||||||
])
|
])
|
||||||
let hint = getHint(entry)
|
let hint = getHint(entry)
|
||||||
if hint.len > 0:
|
if hint.len > 0:
|
||||||
result.add(indent & "└─" & hint & "\n")
|
result.add(spaces(indent+2) & "## " & hint & "\n")
|
||||||
|
|
||||||
proc injectStacktrace[T](future: Future[T]) =
|
proc injectStacktrace[T](future: Future[T]) =
|
||||||
when not defined(release):
|
when not defined(release):
|
||||||
|
|
@ -306,7 +279,7 @@ proc injectStacktrace[T](future: Future[T]) =
|
||||||
|
|
||||||
var newMsg = exceptionMsg & header
|
var newMsg = exceptionMsg & header
|
||||||
|
|
||||||
let entries = getStackTraceEntries(future.error).mergeEntries()
|
let entries = getStackTraceEntries(future.error)
|
||||||
newMsg.add($entries)
|
newMsg.add($entries)
|
||||||
|
|
||||||
newMsg.add("Exception message: " & exceptionMsg & "\n")
|
newMsg.add("Exception message: " & exceptionMsg & "\n")
|
||||||
|
|
|
||||||
|
|
@ -4,42 +4,56 @@ discard """
|
||||||
output: '''
|
output: '''
|
||||||
b failure
|
b failure
|
||||||
Async traceback:
|
Async traceback:
|
||||||
tasync_traceback.nim(83) tasync_traceback
|
tasync_traceback.nim(97) tasync_traceback
|
||||||
asyncmacro.nim(393) a
|
asyncmacro.nim(395) a
|
||||||
asyncmacro.nim(43) a_continue
|
|
||||||
└─Resumes an async procedure
|
|
||||||
asyncfutures.nim(211) callback=
|
|
||||||
asyncfutures.nim(190) addCallback
|
|
||||||
asyncfutures.nim(53) callSoon
|
|
||||||
asyncmacro.nim(34) a_continue
|
asyncmacro.nim(34) a_continue
|
||||||
└─Resumes an async procedure
|
## Resumes an async procedure
|
||||||
asyncmacro.nim(0) aIter
|
tasync_traceback.nim(95) aIter
|
||||||
asyncfutures.nim(341) read
|
asyncmacro.nim(395) b
|
||||||
asyncmacro.nim(34) a_continue
|
|
||||||
└─Resumes an async procedure
|
|
||||||
tasync_traceback.nim(81) aIter
|
|
||||||
asyncmacro.nim(393) b
|
|
||||||
asyncmacro.nim(34) b_continue
|
asyncmacro.nim(34) b_continue
|
||||||
└─Resumes an async procedure
|
## Resumes an async procedure
|
||||||
tasync_traceback.nim(78) bIter
|
tasync_traceback.nim(92) bIter
|
||||||
|
#[
|
||||||
|
tasync_traceback.nim(97) tasync_traceback
|
||||||
|
asyncmacro.nim(395) a
|
||||||
|
asyncmacro.nim(43) a_continue
|
||||||
|
## Resumes an async procedure
|
||||||
|
asyncfutures.nim(211) callback=
|
||||||
|
asyncfutures.nim(190) addCallback
|
||||||
|
asyncfutures.nim(53) callSoon
|
||||||
|
asyncmacro.nim(34) a_continue
|
||||||
|
## Resumes an async procedure
|
||||||
|
asyncmacro.nim(0) aIter
|
||||||
|
asyncfutures.nim(304) read
|
||||||
|
]#
|
||||||
Exception message: b failure
|
Exception message: b failure
|
||||||
Exception type:
|
Exception type:
|
||||||
|
|
||||||
bar failure
|
bar failure
|
||||||
Async traceback:
|
Async traceback:
|
||||||
tasync_traceback.nim(99) tasync_traceback
|
tasync_traceback.nim(113) tasync_traceback
|
||||||
asyncdispatch.nim(1204) waitFor
|
asyncdispatch.nim(1492) waitFor
|
||||||
asyncdispatch.nim(1253) poll
|
asyncdispatch.nim(1496) poll
|
||||||
└─Processes asynchronous completion events
|
## Processes asynchronous completion events
|
||||||
asyncdispatch.nim(181) processPendingCallbacks
|
asyncdispatch.nim(1262) runOnce
|
||||||
└─Executes pending callbacks
|
asyncdispatch.nim(183) processPendingCallbacks
|
||||||
asyncmacro.nim(34) foo_continue
|
## Executes pending callbacks
|
||||||
└─Resumes an async procedure
|
asyncmacro.nim(34) bar_continue
|
||||||
asyncmacro.nim(0) fooIter
|
## Resumes an async procedure
|
||||||
asyncfutures.nim(341) read
|
tasync_traceback.nim(108) barIter
|
||||||
asyncmacro.nim(34) bar_continue
|
#[
|
||||||
└─Resumes an async procedure
|
tasync_traceback.nim(113) tasync_traceback
|
||||||
tasync_traceback.nim(94) barIter
|
asyncdispatch.nim(1492) waitFor
|
||||||
|
asyncdispatch.nim(1496) poll
|
||||||
|
## Processes asynchronous completion events
|
||||||
|
asyncdispatch.nim(1262) runOnce
|
||||||
|
asyncdispatch.nim(183) processPendingCallbacks
|
||||||
|
## Executes pending callbacks
|
||||||
|
asyncmacro.nim(34) foo_continue
|
||||||
|
## Resumes an async procedure
|
||||||
|
asyncmacro.nim(0) fooIter
|
||||||
|
asyncfutures.nim(304) read
|
||||||
|
]#
|
||||||
Exception message: bar failure
|
Exception message: bar failure
|
||||||
Exception type:'''
|
Exception type:'''
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue