MCPcopy Index your code
hub / github.com/RustPython/RustPython / handle_exception

Method handle_exception

crates/vm/src/frame.rs:1558–1606  ·  view source on GitHub ↗
(
                        frame: &mut ExecutingFrame<'_>,
                        exception: PyBaseExceptionRef,
                        idx: usize,
                        is_reraise: bool,
         

Source from the content-addressed store, hash-verified

1556 Err(exception) => {
1557 #[cold]
1558 fn handle_exception(
1559 frame: &mut ExecutingFrame<'_>,
1560 exception: PyBaseExceptionRef,
1561 idx: usize,
1562 is_reraise: bool,
1563 is_new_raise: bool,
1564 vm: &VirtualMachine,
1565 ) -> FrameResult {
1566 // 1. Extract traceback from exception's '__traceback__' attr.
1567 // 2. Add new entry with current execution position (filename, lineno, code_object) to traceback.
1568 // 3. First, try to find handler in exception table
1569
1570 // RERAISE instructions should not add traceback entries - they're just
1571 // re-raising an already-processed exception
1572 if !is_reraise {
1573 // Check if the exception already has traceback entries before
1574 // we add ours. If it does, it was propagated from a callee
1575 // function and we should not re-contextualize it.
1576 let had_prior_traceback = exception.__traceback__().is_some();
1577
1578 // PyTraceBack_Here always adds a new entry without
1579 // checking for duplicates. Each time an exception passes through
1580 // a frame (e.g., in a loop with repeated raise statements),
1581 // a new traceback entry is added.
1582 let (loc, _end_loc) = frame.code.locations[idx];
1583 let next = exception.__traceback__();
1584
1585 let new_traceback = PyTraceback::new(
1586 next,
1587 frame.object.to_owned(),
1588 idx as u32 * 2,
1589 loc.line,
1590 );
1591 vm_trace!("Adding to traceback: {:?} {:?}", new_traceback, loc.line);
1592 exception.set_traceback_typed(Some(new_traceback.into_ref(&vm.ctx)));
1593
1594 // _PyErr_SetObject sets __context__ only when the exception
1595 // is first raised. When an exception propagates through frames,
1596 // __context__ must not be overwritten. We contextualize when:
1597 // - It's an explicit raise (raise/raise from)
1598 // - The exception had no prior traceback (originated here)
1599 if is_new_raise || !had_prior_traceback {
1600 vm.contextualize_exception(&exception);
1601 }
1602 }
1603
1604 // Use exception table for zero-cost exception handling
1605 frame.unwind_blocks(vm, UnwindReason::Raising { exception })
1606 }
1607
1608 // Check if this is a RERAISE instruction
1609 // Both AnyInstruction::Raise { kind: Reraise/ReraiseFromStack } and

Callers

nothing calls this directly

Calls 8

newFunction · 0.85
__traceback__Method · 0.80
set_traceback_typedMethod · 0.80
unwind_blocksMethod · 0.80
SomeClass · 0.50
to_ownedMethod · 0.45
into_refMethod · 0.45

Tested by

no test coverage detected