shape_ext_python/
error_mapping.rs1use crate::runtime::CompiledFunction;
4
5#[derive(Debug, Clone)]
7pub struct PythonFrame {
8 pub filename: String,
9 pub line: u32,
10 pub function: String,
11 pub text: Option<String>,
12}
13
14pub fn parse_traceback(_traceback: &str) -> Vec<PythonFrame> {
16 Vec::new()
17}
18
19pub fn map_python_line_to_shape(python_line: u32, shape_body_start_line: u32) -> u32 {
22 if python_line < 2 {
23 shape_body_start_line
24 } else {
25 shape_body_start_line + (python_line - 1)
26 }
27}
28
29#[cfg(feature = "pyo3")]
31pub fn format_python_error(
32 py: pyo3::Python<'_>,
33 err: &pyo3::PyErr,
34 func: &CompiledFunction,
35) -> String {
36 use pyo3::types::PyTracebackMethods;
37 let traceback_str = err
38 .traceback(py)
39 .and_then(|tb| tb.format().ok())
40 .unwrap_or_default();
41
42 let mut shape_line = None;
44 for line in traceback_str.lines() {
45 if line.contains("<shape>") || line.contains("__shape__") {
46 if let Some(pos) = line.find("line ") {
48 let after = &line[pos + 5..];
49 if let Some(end) = after.find(|c: char| !c.is_ascii_digit()) {
50 if let Ok(py_line) = after[..end].parse::<u32>() {
51 shape_line = Some(map_python_line_to_shape(
52 py_line,
53 func.shape_body_start_line,
54 ));
55 }
56 } else if let Ok(py_line) = after.trim().parse::<u32>() {
57 shape_line = Some(map_python_line_to_shape(
58 py_line,
59 func.shape_body_start_line,
60 ));
61 }
62 }
63 }
64 }
65
66 if let Some(line) = shape_line {
67 format!("Python error in '{}' at line {}: {}", func.name, line, err)
68 } else {
69 format!("Python error in '{}': {}", func.name, err)
70 }
71}
72
73#[cfg(not(feature = "pyo3"))]
75pub fn format_python_error(_err: &str, func: &CompiledFunction) -> String {
76 format!("Python error in '{}': pyo3 not enabled", func.name)
77}