0
# Error Handling
1
2
Comprehensive error system with specific error codes for different failure scenarios and validation issues.
3
4
## Capabilities
5
6
### AppError Class
7
8
Custom error class for application-specific errors with error codes and cause tracking.
9
10
```typescript { .api }
11
class AppError extends Error {
12
/** Error code identifier */
13
code?: ErrorCode;
14
/** Original error that caused this error */
15
cause?: Error;
16
17
constructor(errorContext: ErrorContext, error?: NodeJS.ErrnoException);
18
}
19
20
type ErrorCode =
21
| 'Unknown'
22
| 'NoBundles'
23
| 'NoSourceMap'
24
| 'OneSourceSourceMap'
25
| 'UnmappedBytes'
26
| 'InvalidMappingLine'
27
| 'InvalidMappingColumn'
28
| 'CannotSaveFile'
29
| 'CannotCreateTempFile'
30
| 'CannotOpenTempFile'
31
| 'CannotOpenCoverageFile'
32
| 'NoCoverageMatches';
33
```
34
35
**Usage Examples:**
36
37
```typescript
38
import { explore } from "source-map-explorer";
39
40
try {
41
const result = await explore("bundle.js");
42
} catch (error) {
43
// Error handling - note that AppError is not exported from main library
44
console.error(`Error: ${error.message}`);
45
if (error.code) {
46
console.error(`Error code: ${error.code}`);
47
}
48
if (error.cause) {
49
console.error("Caused by:", error.cause.message);
50
}
51
}
52
```
53
54
### Error Message Details
55
56
Error messages are generated internally by the library and provide detailed context about failures. The library uses a consistent error message format that includes specific details based on the error type.
57
58
## Error Code Categories
59
60
### Input Validation Errors
61
62
Errors related to invalid or missing input data.
63
64
```typescript { .api }
65
type InputErrorCode =
66
| 'NoBundles' // No bundles provided for analysis
67
| 'NoSourceMap'; // Source map not found or invalid
68
```
69
70
**NoBundles Error:**
71
- Occurs when empty array or no files provided to explore()
72
- Indicates no valid bundles to analyze
73
- Usually a programming error in calling code
74
75
**NoSourceMap Error:**
76
- Source map file not found at expected location
77
- Inline source map is malformed or missing
78
- Source map comment points to non-existent file
79
80
**Usage Examples:**
81
82
```typescript
83
try {
84
// This will throw NoBundles error
85
const result = await explore([]);
86
} catch (error) {
87
if (error instanceof AppError && error.code === 'NoBundles') {
88
console.error("No bundles provided for analysis");
89
}
90
}
91
92
try {
93
// This might throw NoSourceMap error
94
const result = await explore("bundle-without-sourcemap.js");
95
} catch (error) {
96
if (error instanceof AppError && error.code === 'NoSourceMap') {
97
console.error("Source map not found - make sure bundle includes source map");
98
}
99
}
100
```
101
102
### Source Map Validation Errors
103
104
Errors related to invalid or problematic source map data.
105
106
```typescript { .api }
107
type ValidationErrorCode =
108
| 'OneSourceSourceMap' // Source map contains only one source file
109
| 'InvalidMappingLine' // Mapping references invalid line number
110
| 'InvalidMappingColumn'; // Mapping references invalid column number
111
```
112
113
**OneSourceSourceMap Warning:**
114
- Source map contains only one source file (when analyzing single bundle)
115
- Results in less useful visualization since there's no breakdown
116
- This is a warning, not a fatal error
117
118
**Invalid Mapping Errors:**
119
- Source map contains mappings pointing beyond file boundaries
120
- Can be disabled with `noBorderChecks: true` option
121
- Usually indicates source map generation issues
122
123
**Usage Examples:**
124
125
```typescript
126
import { explore } from "source-map-explorer";
127
128
const result = await explore("single-file-bundle.js");
129
130
// Check for warnings
131
const warnings = result.errors.filter(e => e.isWarning);
132
warnings.forEach(warning => {
133
if (warning.code === 'OneSourceSourceMap') {
134
console.warn("Bundle maps to only one source file - consider analyzing multiple bundles");
135
}
136
});
137
138
// Handle validation errors with relaxed checking
139
try {
140
const result = await explore("problematic-bundle.js", {
141
noBorderChecks: true // Disable strict validation
142
});
143
} catch (error) {
144
if (error instanceof AppError &&
145
(error.code === 'InvalidMappingLine' || error.code === 'InvalidMappingColumn')) {
146
console.error("Source map has invalid mappings - try noBorderChecks: true");
147
}
148
}
149
```
150
151
### File System Errors
152
153
Errors related to file operations and I/O.
154
155
```typescript { .api }
156
type FileSystemErrorCode =
157
| 'CannotSaveFile' // Unable to save output file
158
| 'CannotCreateTempFile' // Unable to create temporary file
159
| 'CannotOpenTempFile'; // Unable to open temporary file in browser
160
```
161
162
**File Save Errors:**
163
- Permission issues when writing output files
164
- Disk space or filesystem limitations
165
- Invalid file paths or directories
166
167
**Temporary File Errors:**
168
- Used when opening HTML visualization in browser
169
- System temporary directory access issues
170
- Browser launch failures
171
172
**Usage Examples:**
173
174
```typescript
175
try {
176
const result = await explore("bundle.js", {
177
output: { format: "html", filename: "/read-only/analysis.html" }
178
});
179
} catch (error) {
180
if (error instanceof AppError && error.code === 'CannotSaveFile') {
181
console.error("Cannot save output file - check permissions and disk space");
182
}
183
}
184
```
185
186
### Coverage Integration Errors
187
188
Errors related to Chrome DevTools coverage data integration.
189
190
```typescript { .api }
191
type CoverageErrorCode =
192
| 'CannotOpenCoverageFile' // Coverage file not found or unreadable
193
| 'NoCoverageMatches'; // No coverage data matches bundle files
194
```
195
196
**Coverage File Errors:**
197
- Coverage JSON file doesn't exist or is unreadable
198
- Invalid JSON format in coverage file
199
- Permission issues accessing coverage file
200
201
**Coverage Matching Errors:**
202
- Coverage data URLs don't match bundle source files
203
- Different path formats between coverage and source map
204
- No overlap between coverage and bundle data
205
206
**Usage Examples:**
207
208
```typescript
209
try {
210
const result = await explore("bundle.js", {
211
coverage: "non-existent-coverage.json"
212
});
213
} catch (error) {
214
if (error instanceof AppError && error.code === 'CannotOpenCoverageFile') {
215
console.error("Coverage file not found - check path and permissions");
216
}
217
}
218
219
// Handle coverage matching issues
220
const result = await explore("bundle.js", {
221
coverage: "coverage.json"
222
});
223
224
const coverageErrors = result.errors.filter(e => e.code === 'NoCoverageMatches');
225
if (coverageErrors.length > 0) {
226
console.warn("Coverage data doesn't match bundle files - check URL patterns");
227
}
228
```
229
230
## Result-Level Error Handling
231
232
Analysis can partially succeed with some bundles failing. Errors are collected in the result object:
233
234
```typescript
235
const result = await explore(["good-bundle.js", "bad-bundle.js"]);
236
237
// Check for partial failures
238
if (result.bundles.length > 0 && result.errors.length > 0) {
239
console.log(`Analyzed ${result.bundles.length} bundles successfully`);
240
console.log(`${result.errors.length} bundles failed`);
241
242
// Process successful results
243
result.bundles.forEach(bundle => {
244
console.log(`${bundle.bundleName}: ${bundle.totalBytes} bytes`);
245
});
246
247
// Handle failed bundles
248
result.errors.forEach(error => {
249
console.error(`Failed to analyze ${error.bundleName}: ${error.message}`);
250
});
251
}
252
253
// Check for complete failure
254
if (result.bundles.length === 0) {
255
console.error("All bundles failed to analyze");
256
throw new Error("Analysis failed completely");
257
}
258
```
259
260
## Error Recovery Strategies
261
262
### Relaxed Validation
263
264
For problematic source maps, disable strict validation:
265
266
```typescript
267
const result = await explore("problematic-bundle.js", {
268
noBorderChecks: true // Skip mapping boundary validation
269
});
270
```
271
272
### Alternative Input Formats
273
274
Try different input approaches if one fails:
275
276
```typescript
277
async function analyzeWithFallback(bundlePath: string) {
278
try {
279
// Try with automatic source map detection
280
return await explore(bundlePath);
281
} catch (error) {
282
if (error instanceof AppError && error.code === 'NoSourceMap') {
283
try {
284
// Try with explicit source map
285
return await explore({
286
code: bundlePath,
287
map: bundlePath + '.map'
288
});
289
} catch (secondError) {
290
// Try inline source map only
291
return await explore(bundlePath, { excludeSourceMapComment: false });
292
}
293
}
294
throw error;
295
}
296
}
297
```
298
299
### Coverage Data Handling
300
301
Graceful handling of coverage integration issues:
302
303
```typescript
304
async function analyzeWithOptionalCoverage(bundlePath: string, coveragePath?: string) {
305
const baseOptions = {
306
output: { format: "html" as const }
307
};
308
309
if (coveragePath) {
310
try {
311
return await explore(bundlePath, {
312
...baseOptions,
313
coverage: coveragePath
314
});
315
} catch (error) {
316
if (error instanceof AppError &&
317
(error.code === 'CannotOpenCoverageFile' || error.code === 'NoCoverageMatches')) {
318
console.warn("Coverage integration failed, continuing without coverage data");
319
return await explore(bundlePath, baseOptions);
320
}
321
throw error;
322
}
323
}
324
325
return await explore(bundlePath, baseOptions);
326
}
327
```