0
# Error Handling
1
2
Comprehensive error handling system that maps Python exceptions to JavaScript errors with full traceback information and proper error type mapping.
3
4
## Capabilities
5
6
### Python Error Type
7
8
All Python exceptions thrown from pymport operations are mapped to JavaScript errors with additional Python-specific information.
9
10
```typescript { .api }
11
/**
12
* Extended error type that includes Python exception information
13
* Inherits from standard JavaScript Error, TypeError, or RangeError
14
*/
15
type PythonError = (Error | TypeError | RangeError) & {
16
/**
17
* Python exception type as PyObject (e.g., ValueError, KeyError)
18
*/
19
pythonType: PyObject;
20
21
/**
22
* Python exception value/message as PyObject
23
*/
24
pythonValue: PyObject;
25
26
/**
27
* Python traceback information as PyObject
28
*/
29
pythonTrace: PyObject;
30
};
31
```
32
33
### Exception Handling Patterns
34
35
Standard JavaScript try-catch blocks work with Python exceptions, with additional Python context available.
36
37
**Usage Examples:**
38
39
```javascript
40
import { pymport, proxify } from 'pymport';
41
42
const builtins = pymport('builtins');
43
44
try {
45
// This will raise a Python ValueError
46
const result = builtins.get('int').call('not_a_number');
47
} catch (error) {
48
// Check if it's a Python error
49
if (error.pythonType) {
50
console.log('Python Exception Type:', error.pythonType.toString());
51
console.log('Python Exception Value:', error.pythonValue.toString());
52
console.log('JavaScript Error Message:', error.message);
53
54
// Check specific Python exception types
55
const pythonTypeName = error.pythonType.get('__name__').toString();
56
if (pythonTypeName === 'ValueError') {
57
console.log('Handling ValueError specifically');
58
}
59
}
60
}
61
```
62
63
### Common Python Exception Types
64
65
Python exceptions are mapped to appropriate JavaScript error types while preserving Python-specific information.
66
67
**ValueError (TypeError in JS):**
68
```javascript
69
try {
70
const int = builtins.get('int');
71
int.call('abc'); // Invalid literal for int()
72
} catch (error) {
73
console.log(error instanceof TypeError); // true
74
console.log(error.pythonType.get('__name__').toString()); // 'ValueError'
75
}
76
```
77
78
**KeyError (Error in JS):**
79
```javascript
80
try {
81
const dict = PyObject.dict({ a: 1, b: 2 });
82
dict.item('nonexistent_key');
83
} catch (error) {
84
console.log(error instanceof Error); // true
85
console.log(error.pythonType.get('__name__').toString()); // 'KeyError'
86
console.log(error.message); // "'nonexistent_key'"
87
}
88
```
89
90
**IndexError (RangeError in JS):**
91
```javascript
92
try {
93
const list = PyObject.list([1, 2, 3]);
94
list.item(10); // Index out of range
95
} catch (error) {
96
console.log(error instanceof RangeError); // true
97
console.log(error.pythonType.get('__name__').toString()); // 'IndexError'
98
}
99
```
100
101
**AttributeError (Error in JS):**
102
```javascript
103
try {
104
const obj = PyObject.string('hello');
105
obj.get('nonexistent_method');
106
} catch (error) {
107
console.log(error instanceof Error); // true
108
console.log(error.pythonType.get('__name__').toString()); // 'AttributeError'
109
}
110
```
111
112
### Async Error Handling
113
114
Asynchronous operations return Promise rejections with the same Python error information.
115
116
**Usage Examples:**
117
118
```javascript
119
import { pymport, proxify } from 'pymport';
120
121
const asyncFunction = proxify(pymport('asyncio')).sleep;
122
123
try {
124
// Async operations that may fail
125
const result = await asyncFunction.callAsync(-1); // Invalid argument
126
} catch (error) {
127
if (error.pythonType) {
128
console.log('Async Python Error:', error.pythonType.toString());
129
console.log('Traceback:', error.pythonTrace.toString());
130
}
131
}
132
133
// Promise-based error handling
134
asyncFunction.callAsync('invalid')
135
.then(result => {
136
console.log('Success:', result);
137
})
138
.catch(error => {
139
if (error.pythonTrace) {
140
console.log('Python traceback available');
141
}
142
});
143
```
144
145
### Context Manager Error Handling
146
147
Errors in Python context managers (with statements) are properly handled with cleanup.
148
149
**Usage Examples:**
150
151
```javascript
152
import { pymport } from 'pymport';
153
154
const builtins = pymport('builtins');
155
const open = builtins.get('open');
156
157
try {
158
const file = open.call('nonexistent.txt', 'r');
159
file.with((f) => {
160
// This will fail due to file not existing
161
return f.get('read').call();
162
});
163
} catch (error) {
164
// File is automatically closed even on error
165
if (error.pythonType) {
166
const exceptionName = error.pythonType.get('__name__').toString();
167
if (exceptionName === 'FileNotFoundError') {
168
console.log('File not found, creating default...');
169
}
170
}
171
}
172
173
// Custom context manager error handling
174
const customContext = pyval('some_custom_context_manager()');
175
try {
176
customContext.with((ctx) => {
177
throw new Error('JavaScript error in context');
178
});
179
} catch (error) {
180
// Context manager's __exit__ method is called with error info
181
console.log('Error handled by context manager');
182
}
183
```
184
185
### Function Call Error Handling
186
187
Errors from Python function calls include detailed parameter and call information.
188
189
**Usage Examples:**
190
191
```javascript
192
const np = proxify(pymport('numpy'));
193
194
try {
195
// Invalid array creation
196
const arr = np.array('not_an_array');
197
} catch (error) {
198
console.log('Function call failed:', error.message);
199
200
if (error.pythonTrace) {
201
// Get detailed traceback
202
const traceStr = error.pythonTrace.toString();
203
console.log('Full Python traceback:');
204
console.log(traceStr);
205
}
206
}
207
208
try {
209
// Invalid reshape operation
210
const arr = np.array([1, 2, 3]);
211
arr.reshape(2, 3); // Can't reshape 3 elements to 2x3
212
} catch (error) {
213
const errorType = error.pythonType.get('__name__').toString();
214
if (errorType === 'ValueError') {
215
console.log('Reshape dimension mismatch');
216
}
217
}
218
```
219
220
### Import Error Handling
221
222
Module import failures provide clear error information.
223
224
**Usage Examples:**
225
226
```javascript
227
import { pymport } from 'pymport';
228
229
try {
230
const nonexistent = pymport('nonexistent_module');
231
} catch (error) {
232
if (error.pythonType) {
233
const errorType = error.pythonType.get('__name__').toString();
234
if (errorType === 'ModuleNotFoundError') {
235
console.log('Module not found. Install with: npx pympip install module_name');
236
}
237
}
238
}
239
240
try {
241
// Module exists but has syntax errors
242
const broken = pymport('broken_syntax_module');
243
} catch (error) {
244
if (error.pythonType) {
245
const errorType = error.pythonType.get('__name__').toString();
246
if (errorType === 'SyntaxError') {
247
console.log('Python module has syntax errors');
248
console.log('Error details:', error.pythonValue.toString());
249
}
250
}
251
}
252
```
253
254
### Error Recovery Strategies
255
256
Common patterns for handling and recovering from Python errors.
257
258
**Usage Examples:**
259
260
```javascript
261
// Retry with different parameters
262
function safeArrayCreation(data, dtype = null) {
263
const np = proxify(pymport('numpy'));
264
265
try {
266
return np.array(data, dtype ? { dtype } : {});
267
} catch (error) {
268
if (error.pythonType?.get('__name__').toString() === 'ValueError') {
269
console.log('Retrying without dtype specification...');
270
try {
271
return np.array(data);
272
} catch (retryError) {
273
console.log('Array creation failed completely');
274
throw retryError;
275
}
276
}
277
throw error;
278
}
279
}
280
281
// Graceful degradation
282
function getModuleOrFallback(primaryModule, fallbackModule) {
283
try {
284
return pymport(primaryModule);
285
} catch (error) {
286
if (error.pythonType?.get('__name__').toString() === 'ModuleNotFoundError') {
287
console.log(`${primaryModule} not available, using ${fallbackModule}`);
288
return pymport(fallbackModule);
289
}
290
throw error;
291
}
292
}
293
294
// Error logging and monitoring
295
function withErrorLogging(operation) {
296
try {
297
return operation();
298
} catch (error) {
299
if (error.pythonTrace) {
300
// Log Python-specific error details
301
console.error('Python Error Details:', {
302
type: error.pythonType.toString(),
303
value: error.pythonValue.toString(),
304
traceback: error.pythonTrace.toString(),
305
jsMessage: error.message,
306
jsStack: error.stack
307
});
308
}
309
throw error;
310
}
311
}
312
```