GeoLeaf.Errors — Errors module documentation
Applies to: @geoleaf/core v3.x
Source: src/modules/utils/errors/index.ts
Overview
The GeoLeaf.Errors module provides typed error classes for consistent, contextual error handling across the whole GeoLeaf library.
Benefits of typed errors
- Targeted catch — tell error types apart with
instanceof - Richer context — additional debugging data (
error.context) - Clean stack trace — call stack preserved through
captureStackTrace - Serialisable — JSON conversion through
toJSON() - Timestamp — automatic time stamping (
error.timestamp) - Error code — machine-readable identifier (
error.code)
Error hierarchy
Error (native)
└─ GeoLeafError (base)
├─ ValidationError VALIDATION_ERROR
├─ SecurityError SECURITY_ERROR
├─ ConfigError CONFIG_ERROR
├─ NetworkError NETWORK_ERROR
├─ InitializationError INITIALIZATION_ERROR
├─ MapError MAP_ERROR
├─ DataError DATA_ERROR
├─ POIError POI_ERROR
├─ RouteError ROUTE_ERROR
└─ UIError UI_ERRORError classes
GeoLeafError (base)
Base class for every GeoLeaf error. It extends the native Error.
Properties:
| Property | Type | Description |
|---|---|---|
name | string | Class name (for example 'ValidationError') |
message | string | Error message |
context | ErrorContext | Additional context data |
timestamp | string | ISO 8601 creation time |
code | string | Machine code (defined in each subclass) |
stack | string | Stack trace |
Methods:
toJSON()— returns a serialisable object{ name, message, context, timestamp, stack }toString()— readable formatting with context:"ErrorName: message [Context: {...}]"
const error = new GeoLeaf.Errors.GeoLeafError("Generic error", {
module: "Core",
operation: "init",
});
console.log(error.name); // 'GeoLeafError'
console.log(error.message); // 'Generic error'
console.log(error.context); // { module: 'Core', operation: 'init' }
console.log(error.timestamp); // '2026-03-15T10:30:00.000Z'
console.log(error.code); // undefined (base class)ValidationError
Data validation error. Code: VALIDATION_ERROR
Used for:
- Invalid coordinates
- Missing or incorrect parameters
- Non-conforming data format
throw new GeoLeaf.Errors.ValidationError("Latitude must be between -90 and 90", {
lat: 95,
lng: -73,
expected: "Range: -90 to 90",
});
// Targeted catch
try {
GeoLeaf.Core.init({/* options */});
} catch (error) {
if (error instanceof GeoLeaf.Errors.ValidationError) {
console.error("Validation error:", error.context);
}
}SecurityError
Security issue detected. Code: SECURITY_ERROR
Used for:
- XSS content detection
- Disallowed URL protocol
- Non-image data URL
throw new GeoLeaf.Errors.SecurityError("Protocol not allowed: javascript:", {
url: "javascript:alert(1)",
allowedProtocols: ["http:", "https:", "data:"],
});
try {
GeoLeaf.Validators.validateUrl(userUrl, { throwOnError: true });
} catch (error) {
if (error instanceof GeoLeaf.Errors.SecurityError) {
console.error("Security attempt detected");
// Log it for analysis
}
}ConfigError
Configuration error. Code: CONFIG_ERROR
Used for:
- Invalid JSON configuration
- Missing configuration field
- Incorrect profile structure
throw new GeoLeaf.Errors.ConfigError("Invalid profile structure: missing layers", {
profileId: "tourism",
expected: "Array",
received: "undefined",
});
try {
GeoLeaf.Config.loadProfile("tourism");
} catch (error) {
if (error instanceof GeoLeaf.Errors.ConfigError) {
console.error("Incorrect configuration:", error.message);
}
}NetworkError
Network or HTTP error. Code: NETWORK_ERROR
Used for:
fetch()failure- Network timeout
- HTTP 4xx/5xx status
throw new GeoLeaf.Errors.NetworkError("Failed to load POI data", {
url: "/api/poi",
status: 404,
statusText: "Not Found",
});
async function loadWithRetry() {
try {
return await GeoLeaf.Config.loadConfig("config.json");
} catch (error) {
if (error instanceof GeoLeaf.Errors.NetworkError) {
console.warn("Retrying in 3s...");
await GeoLeaf.Helpers.wait(3000);
return await GeoLeaf.Config.loadConfig("config.json");
}
throw error;
}
}InitializationError
Error raised during initialisation. Code: INITIALIZATION_ERROR
Used for:
- Map creation failure
- DOM element not found
- Missing dependency
throw new GeoLeaf.Errors.InitializationError("Failed to create map: target element not found", {
target: "map-container",
domReady: document.readyState,
});MapError
Error related to the MapLibre map. Code: MAP_ERROR
Used for:
- Invalid map operation
- Invalid bounds
- Layer not found
throw new GeoLeaf.Errors.MapError("Cannot fit bounds: no features loaded", {
operation: "fitBounds",
featureCount: 0,
});DataError
Generic data error. Code: DATA_ERROR
Used for:
- Malformed data not specific to POI/Route/GeoJSON
- Failed data parsing
throw new GeoLeaf.Errors.DataError("Invalid data structure", {
source: "api/response",
expected: "array",
received: typeof data,
});POIError
Error raised while handling POIs. Code: POI_ERROR
Used for:
- Malformed POI
- Failed POI loading
- Invalid marker
throw new GeoLeaf.Errors.POIError("Invalid POI: missing latlng", {
poiId: "poi-123",
provided: { id: "poi-123", label: "Test" },
expected: "latlng: [lat, lng]",
});RouteError
Error raised while processing routes. Code: ROUTE_ERROR
Used for:
- Malformed GPX
- Failed GPX parsing
- Empty route
throw new GeoLeaf.Errors.RouteError("Failed to parse GPX: invalid XML", {
url: "route.gpx",
parseError: "Unexpected end of input",
});UIError
Error related to the user interface. Code: UI_ERROR
Used for:
- UI component not initialised
- Failed rendering
- DOM element missing during a UI operation
throw new GeoLeaf.Errors.UIError("Panel render failed: container not found", {
panelId: "sidepanel",
operation: "render",
});Constants
ErrorCodes
Immutable object listing every error code:
GeoLeaf.Errors.ErrorCodes.VALIDATION; // 'VALIDATION_ERROR'
GeoLeaf.Errors.ErrorCodes.SECURITY; // 'SECURITY_ERROR'
GeoLeaf.Errors.ErrorCodes.CONFIG; // 'CONFIG_ERROR'
GeoLeaf.Errors.ErrorCodes.NETWORK; // 'NETWORK_ERROR'
GeoLeaf.Errors.ErrorCodes.INITIALIZATION; // 'INITIALIZATION_ERROR'
GeoLeaf.Errors.ErrorCodes.MAP; // 'MAP_ERROR'
GeoLeaf.Errors.ErrorCodes.DATA; // 'DATA_ERROR'
GeoLeaf.Errors.ErrorCodes.POI; // 'POI_ERROR'
GeoLeaf.Errors.ErrorCodes.ROUTE; // 'ROUTE_ERROR'
GeoLeaf.Errors.ErrorCodes.UI; // 'UI_ERROR'Utility functions
normalizeError(error, defaultMessage?)
Normalises any value into a GeoLeafError.
try {
// risky code
} catch (rawError) {
const err = GeoLeaf.Errors.normalizeError(rawError, "Unexpected error");
GeoLeaf.Log.error(err.toString());
}isErrorType(error, ErrorClass)
Checks whether an error is an instance of a given class.
const isConfig = GeoLeaf.Errors.isErrorType(error, GeoLeaf.Errors.ConfigError);getErrorCode(error)
Extracts the error code from any value.
const code = GeoLeaf.Errors.getErrorCode(error);
// 'VALIDATION_ERROR' | 'CONFIG_ERROR' | ... | 'UNKNOWN_ERROR'createError(ErrorClass, message, context?)
Creates a typed error instance with a clean stack trace.
const err = GeoLeaf.Errors.createError(GeoLeaf.Errors.ValidationError, "Invalid zoom level", {
zoom: 25,
max: 20,
});createErrorByType(type, message, context?)
Creates an error from its type given as a string.
const err = GeoLeaf.Errors.createErrorByType("validation", "Invalid value", { value: 42 });
// Returns a ValidationError instanceSupported types: 'validation', 'security', 'config', 'network', 'initialization', 'map', 'data', 'poi', 'route', 'ui'
sanitizeErrorMessage(message, maxLength?)
Sanitises an error message (HTML escaping, truncation).
const safe = GeoLeaf.Errors.sanitizeErrorMessage(userInput, 500);safeErrorHandler(handler, error)
Runs an error handler safely (guards against errors thrown inside handlers).
GeoLeaf.Errors.safeErrorHandler(onError, caughtError);Usage patterns
Pattern 1: validation with a typed error
function validatePOI(poi) {
if (!poi.latlng || !Array.isArray(poi.latlng)) {
throw new GeoLeaf.Errors.ValidationError("POI must have latlng array", {
poiId: poi.id,
provided: poi.latlng,
});
}
GeoLeaf.Validators.validateCoordinates(poi.latlng[0], poi.latlng[1], {
throwOnError: true,
});
// ValidationError is thrown automatically when invalid
}Pattern 2: multi-level catch
try {
await GeoLeaf.Config.loadConfig("config.json");
} catch (error) {
if (error instanceof GeoLeaf.Errors.NetworkError) {
console.error("Network problem, offline mode enabled");
activateOfflineMode();
} else if (error instanceof GeoLeaf.Errors.ConfigError) {
console.error("Invalid configuration");
showConfigHelp();
} else if (error instanceof GeoLeaf.Errors.SecurityError) {
console.error("Security problem detected");
reportSecurityIssue(error);
} else {
console.error("Unknown error:", error);
}
}Pattern 3: enriched logging
try {
// Risky code
} catch (error) {
if (error instanceof GeoLeaf.Errors.GeoLeafError) {
GeoLeaf.Log.error("[GeoLeaf] Error:", {
type: error.name,
code: error.code,
message: error.message,
context: error.context,
timestamp: error.timestamp,
});
} else {
GeoLeaf.Log.error("[GeoLeaf] Unknown error:", error);
}
}Pattern 4: using normalizeError in generic handlers
async function safeLoad(url) {
try {
const res = await fetch(url);
if (!res.ok) {
throw new GeoLeaf.Errors.NetworkError(`HTTP ${res.status}`, {
url,
status: res.status,
});
}
return await res.json();
} catch (rawError) {
const err = GeoLeaf.Errors.normalizeError(rawError, "Load failed");
GeoLeaf.Log.error("[GeoLeaf] Load error:", err.toString());
throw err;
}
}Tests
npm test -- errors
# Test files
# packages/core/__tests__/core/errors.test.js
# packages/core/__tests__/core/errors-extended.test.jsCoverage: 95%+ (150+ passing tests)
Error statistics
| Error type | Frequency | Criticality |
|---|---|---|
ValidationError | 45% | Medium |
ConfigError | 25% | High |
NetworkError | 15% | Medium |
SecurityError | 5% | High |
| Others | 10% | Variable |
Changelog
v2.0.0 — first official release
- Module created with the base hierarchy:
GeoLeafError,ValidationError,SecurityError,ConfigError,NetworkError,InitializationError,MapError - Added
DataErrorandUIError - Added
ErrorCodes(machine-readable constants) - Added utility functions:
normalizeError,isErrorType,getErrorCode,createError,createErrorByType,sanitizeErrorMessage,safeErrorHandler
See also
GeoLeaf.Validators— usesValidationErrorandSecurityErrorGeoLeaf.Security— usesSecurityErrorGeoLeaf.Config— usesConfigErrorandNetworkErrorGeoLeaf.Log— error logging
