1use crate::ast::Position;
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Clone, Serialize, Deserialize)]
5pub enum RuntimeError {
6 TypeError {
7 message: String,
8 position: Option<Position>,
9 },
10
11 ReferenceError {
12 message: String,
13 position: Option<Position>,
14 },
15
16 RangeError {
17 message: String,
18 position: Option<Position>,
19 },
20
21 SyntaxError {
22 message: String,
23 position: Option<Position>,
24 },
25
26 UndefinedProperty {
27 object: String,
28 property: String,
29 position: Option<Position>,
30 },
31
32 InvalidFunctionCall {
33 function: String,
34 message: String,
35 position: Option<Position>,
36 },
37
38 ContextError {
39 message: String,
40 position: Option<Position>,
41 },
42
43 BuiltinError {
44 builtin: String,
45 message: String,
46 position: Option<Position>,
47 },
48
49 ObjectError {
50 message: String,
51 position: Option<Position>,
52 },
53}
54
55impl std::fmt::Display for RuntimeError {
56 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
57 match self {
58 RuntimeError::TypeError { message, position } => {
59 write!(f, "TypeError: {message}")?;
60 if let Some(pos) = position {
61 write!(f, " at line {}, column {}", pos.line, pos.column)?;
62 }
63 Ok(())
64 }
65 RuntimeError::ReferenceError { message, position } => {
66 write!(f, "ReferenceError: {message}")?;
67 if let Some(pos) = position {
68 write!(f, " at line {}, column {}", pos.line, pos.column)?;
69 }
70 Ok(())
71 }
72 RuntimeError::RangeError { message, position } => {
73 write!(f, "RangeError: {message}")?;
74 if let Some(pos) = position {
75 write!(f, " at line {}, column {}", pos.line, pos.column)?;
76 }
77 Ok(())
78 }
79 RuntimeError::SyntaxError { message, position } => {
80 write!(f, "SyntaxError: {message}")?;
81 if let Some(pos) = position {
82 write!(f, " at line {}, column {}", pos.line, pos.column)?;
83 }
84 Ok(())
85 }
86 RuntimeError::UndefinedProperty {
87 object,
88 property,
89 position,
90 } => {
91 write!(f, "Cannot read property '{property}' of {object}")?;
92 if let Some(pos) = position {
93 write!(f, " at line {}, column {}", pos.line, pos.column)?;
94 }
95 Ok(())
96 }
97 RuntimeError::InvalidFunctionCall {
98 function,
99 message,
100 position,
101 } => {
102 write!(f, "Invalid call to '{function}': {message}")?;
103 if let Some(pos) = position {
104 write!(f, " at line {}, column {}", pos.line, pos.column)?;
105 }
106 Ok(())
107 }
108 RuntimeError::ContextError { message, position } => {
109 write!(f, "Context error: {message}")?;
110 if let Some(pos) = position {
111 write!(f, " at line {}, column {}", pos.line, pos.column)?;
112 }
113 Ok(())
114 }
115 RuntimeError::BuiltinError {
116 builtin,
117 message,
118 position,
119 } => {
120 write!(f, "Builtin '{builtin}' error: {message}")?;
121 if let Some(pos) = position {
122 write!(f, " at line {}, column {}", pos.line, pos.column)?;
123 }
124 Ok(())
125 }
126 RuntimeError::ObjectError { message, position } => {
127 write!(f, "Object error: {message}")?;
128 if let Some(pos) = position {
129 write!(f, " at line {}, column {}", pos.line, pos.column)?;
130 }
131 Ok(())
132 }
133 }
134 }
135}
136
137impl std::error::Error for RuntimeError {}