Attach and build upon partial tracebacks
If an exception is raised within a 'try', attach a traceback only up until that 'try'. If a re-raised exception has a traceback already, attach the new traceback "above" the existing one.
This commit is contained in:
parent
85ad910f23
commit
f38a451f19
35
src/vm.c
35
src/vm.c
@ -263,16 +263,28 @@ void krk_dumpTraceback(void) {
|
||||
static void attachTraceback(void) {
|
||||
if (IS_INSTANCE(krk_currentThread.currentException)) {
|
||||
KrkInstance * theException = AS_INSTANCE(krk_currentThread.currentException);
|
||||
|
||||
/* If there already is a traceback, don't add a new one; this exception was re-raised. */
|
||||
KrkValue existing;
|
||||
if (krk_tableGet(&theException->fields, OBJECT_VAL(S("traceback")), &existing)) return;
|
||||
|
||||
KrkValue tracebackList = krk_list_of(0,NULL,0);
|
||||
KrkValue tracebackList;
|
||||
if (krk_tableGet(&theException->fields, OBJECT_VAL(S("traceback")), &tracebackList)) {
|
||||
krk_push(tracebackList);
|
||||
} else {
|
||||
krk_push(NONE_VAL());
|
||||
}
|
||||
tracebackList = krk_list_of(0,NULL,0);
|
||||
krk_push(tracebackList);
|
||||
|
||||
/* Build the traceback object */
|
||||
if (krk_currentThread.frameCount) {
|
||||
for (size_t i = 0; i < krk_currentThread.frameCount; i++) {
|
||||
|
||||
/* Go up until we get to the exit frame */
|
||||
size_t frameOffset = 0;
|
||||
if (krk_currentThread.stackTop > krk_currentThread.stack) {
|
||||
size_t stackOffset = krk_currentThread.stackTop - krk_currentThread.stack - 1;
|
||||
while (stackOffset > 0 && !IS_TRY_HANDLER(krk_currentThread.stack[stackOffset])) stackOffset--;
|
||||
frameOffset = krk_currentThread.frameCount - 1;
|
||||
while (frameOffset > 0 && krk_currentThread.frames[frameOffset].slots > stackOffset) frameOffset--;
|
||||
}
|
||||
|
||||
for (size_t i = frameOffset; i < krk_currentThread.frameCount; i++) {
|
||||
KrkCallFrame * frame = &krk_currentThread.frames[i];
|
||||
KrkTuple * tbEntry = krk_newTuple(2);
|
||||
krk_push(OBJECT_VAL(tbEntry));
|
||||
@ -282,8 +294,17 @@ static void attachTraceback(void) {
|
||||
krk_pop();
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_list(krk_peek(1))) {
|
||||
KrkValueArray * existingTraceback = AS_LIST(krk_peek(1));
|
||||
for (size_t i = 0; i < existingTraceback->count; ++i) {
|
||||
krk_writeValueArray(AS_LIST(tracebackList), existingTraceback->values[i]);
|
||||
}
|
||||
}
|
||||
|
||||
krk_attachNamedValue(&theException->fields, "traceback", tracebackList);
|
||||
krk_pop();
|
||||
krk_pop();
|
||||
} /* else: probably a legacy 'raise str', just don't bother. */
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
Caught a TypeError('A type error')
|
||||
File 'test/testExceptionTracebacks.krk', line 14, in <module>
|
||||
File 'test/testExceptionTracebacks.krk', line 4, in doTheThing
|
||||
Caught a ValueError('A value error')
|
||||
File 'test/testExceptionTracebacks.krk', line 15, in <module>
|
||||
File 'test/testExceptionTracebacks.krk', line 4, in doTheThing
|
||||
That's a name error!
|
||||
|
39
test/testReraisedExceptionTracebacks.krk
Normal file
39
test/testReraisedExceptionTracebacks.krk
Normal file
@ -0,0 +1,39 @@
|
||||
def foo():
|
||||
try:
|
||||
raise ValueError("oh no")
|
||||
except Exception as e:
|
||||
raise e
|
||||
|
||||
if True:
|
||||
try:
|
||||
foo()
|
||||
except Exception as e:
|
||||
print("Traceback entries")
|
||||
for i in e.traceback:
|
||||
let func, instr = i
|
||||
print(f" File '{func.__file__}', line {func._ip_to_line(instr)}, in {func.__name__}")
|
||||
else:
|
||||
foo()
|
||||
|
||||
def bar(n):
|
||||
if n == 3:
|
||||
raise ValueError(n)
|
||||
else:
|
||||
bar(n+1)
|
||||
|
||||
if True:
|
||||
try:
|
||||
try:
|
||||
bar(0)
|
||||
except Exception as e:
|
||||
raise e
|
||||
except Exception as e:
|
||||
print("Traceback entries")
|
||||
for i in e.traceback:
|
||||
let func, instr = i
|
||||
print(f" File '{func.__file__}', line {func._ip_to_line(instr)}, in {func.__name__}")
|
||||
else:
|
||||
try:
|
||||
bar(0)
|
||||
except Exception as e:
|
||||
raise e
|
11
test/testReraisedExceptionTracebacks.krk.expect
Normal file
11
test/testReraisedExceptionTracebacks.krk.expect
Normal file
@ -0,0 +1,11 @@
|
||||
Traceback entries
|
||||
File 'test/testReraisedExceptionTracebacks.krk', line 9, in <module>
|
||||
File 'test/testReraisedExceptionTracebacks.krk', line 5, in foo
|
||||
File 'test/testReraisedExceptionTracebacks.krk', line 3, in foo
|
||||
Traceback entries
|
||||
File 'test/testReraisedExceptionTracebacks.krk', line 29, in <module>
|
||||
File 'test/testReraisedExceptionTracebacks.krk', line 27, in <module>
|
||||
File 'test/testReraisedExceptionTracebacks.krk', line 22, in bar
|
||||
File 'test/testReraisedExceptionTracebacks.krk', line 22, in bar
|
||||
File 'test/testReraisedExceptionTracebacks.krk', line 22, in bar
|
||||
File 'test/testReraisedExceptionTracebacks.krk', line 20, in bar
|
Loading…
Reference in New Issue
Block a user