Error Handling and Debugging
Relevant source files
The following files were used as context for generating this wiki page:
Error handling in gr8hopper is designed to be robust and predictable, providing clear feedback for developers and administrators while ensuring graceful failure for end-users. The system distinguishes between fatal startup/configuration errors, structured API errors for the admin panel, and fallback mechanisms for public-facing redirects. This ensures that misconfigurations are caught early, administrative actions receive clear responses, and user traffic is never left at a dead end.
Debugging is facilitated through intentional design choices, such as visible placeholder errors in destination URLs and a comprehensive Admin UI that provides immediate feedback and tools for testing route configurations. The system prioritizes security by validating all inputs and sanitizing data to prevent common vulnerabilities.
Startup and Configuration Errors
The application performs critical environment checks at startup. The error handling strategy differs between the Node.js server and the Cloudflare Workers deployment.
Node.js Server
The Node.js server (server.ts) treats missing administrative credentials as a fatal error, preventing the server from starting in an insecure state. It also handles storage initialization failures gracefully.
The diagram below illustrates the startup validation sequence for the Node.js server.
- Credential Validation: The server will refuse to start if
ADMIN_USERNAMEorADMIN_PASSWORDare not set in the environment. It also rejects the generic username 'admin' to enforce better security practices. - Process Exit: On a fatal configuration error, a descriptive message is logged to the console, and the process terminates with an exit code of
1. - Storage Initialization: If the
JsonFileAdapterfails to initialize (e.g., due to file permission issues), it is also treated as a fatal error.
Sources: src/server.ts:70-125
Cloudflare Workers
The Cloudflare Workers entry point (index.ts) handles configuration errors by returning an HTTP 500 status code with a plain text error message, as it cannot terminate the worker process.
- HTTP 500 Errors: If
ROUTES_KV,ADMIN_USERNAME, orADMIN_PASSWORDare not configured in the worker's environment, the first request will trigger an initialization failure, resulting in a500 Server misconfigurationresponse. - Console Logging: In addition to the HTTP response, an error message is logged to the worker's console for debugging.
Sources: src/index.ts:28-44
Admin API Error Handling
The admin API, defined in src/handlers/admin.ts, provides structured JSON error responses to the client. All API error handling is centralized within try...catch blocks for each endpoint.
Common API Error Responses
| Status Code | Reason | Example Payload |
|---|---|---|
400 Bad Request | Invalid JSON, missing required fields, or failed validation. | { "error": "Invalid route ID: Nested \"{\" in route ID" } |
401 Unauthorized | Missing or incorrect Basic Auth credentials. | (Handled by basicAuth middleware) |
404 Not Found | The requested route ID does not exist. | { "error": "Route not found" } |
500 Internal Server Error | An unexpected error occurred, often related to storage. | { "error": "Failed to retrieve routes" } |
Sources: src/handlers/admin.ts
API Request Error Flow
The following sequence diagram shows how an error is handled when a user tries to create a new route with an invalid ID through the Admin API.
This diagram shows the validation step failing before any data is written to storage.
Sources: src/handlers/admin.ts:121-127, src/utils/validation.ts:40-79
Import/Export Error Handling
The /import endpoint has a particularly robust error handling mechanism that includes validation, collision detection, and data rollback on failure.
- Upfront Validation: Before any changes are made, the entire import file is parsed and validated. This includes checking for a valid
routesobject, validating each route ID and configuration, and checking for ID collisions that might occur after sanitization. - Atomic Operation with Rollback: To prevent partial updates, the system first backs up all existing routes and settings. It then attempts to perform the import. If any step of the import fails (e.g., writing new routes or settings), it triggers a rollback to restore the original data from the backup.
Sources: src/handlers/admin.ts:318-406
Client-Side Error Display (Admin UI)
The Admin UI uses a non-intrusive "toast" notification system and inline form alerts to provide feedback to the user.
Toast Notifications
A global showToast(message, type) function is used to display success or error messages at the top of the screen. This is used for actions like failing to load routes, failing to delete a route, or a failed import.
// Example from admin-html.ts
function showToast(message, type = 'success', duration = 5000) {
// ... creates and appends a toast element ...
}
// Usage on error
showToast('Failed to delete redirect', 'error');
Sources: src/admin-html.ts:1335-1339, src/admin-html.ts:1493-1495
Form-Specific Errors
When creating or editing a route, if the API returns a validation error (e.g., a 400 Bad Request), the error message is displayed directly within the modal form.
The following diagram shows the flow of a form submission error.
Sources: src/admin-html.ts:1522-1526
Public Redirect Error Handling & Debugging
For public-facing redirects, the system is designed to fail gracefully and provide clear signals for debugging misconfigurations.
Fallback URL
If a requested route is not found or is inactive, gr8hopper redirects the user to the configured fallback_url. If the fallback_url is not an absolute URL (e.g., /not-found), it will result in a 404 response from the server, which can be handled by a custom 404 page.
Sources: README.md
Visible Placeholder Errors
A key debugging feature is how the system handles missing parameters. If a destination template contains a placeholder (e.g., {id}) but the incoming request URL does not provide a value for it, the placeholder is left as-is in the final redirected URL.
Example:
- Route Config:
template: "https://partner.com/product/{id}" - Request:
/?r=my-route(missingidparameter) - Result:
301 Redirect → https://partner.com/product/{id}
This makes it immediately obvious that a parameter was missing from the source link, simplifying the debugging of campaign links or integrations.
Sources: README.md
Input Validation and Sanitization
The src/utils/validation.ts file is central to the application's security and stability, providing functions to validate all user-configurable data.
URL Scheme Validation
To prevent XSS and other attacks via malicious URLs, all template URLs and fallback URLs are validated to ensure they use safe protocols.
| Type | Schemes |
|---|---|
| Allowed | http:, https: |
| Dangerous (Blocked) | javascript:, data:, vbscript:, file:, about:, blob:, filesystem: |
Protocol-relative URLs (e.g., //example.com) are also blocked as a defense-in-depth measure.
Sources: src/utils/validation.ts:8-15, SECURITY.md
Data Sanitization
- URL Sanitization: The
sanitizeUrlfunction removes ASCII control characters (like\n,\r) from URLs to prevent CRLF injection and other header injection attacks. - Route ID Sanitization: Route IDs are sanitized to lowercase and allow a specific set of characters for patterns. Backslashes are stripped to prevent potential escape injection issues.
Sources: src/utils/validation.ts:83-87, SECURITY.md
Summary
gr8hopper employs a multi-layered approach to error handling and debugging. Fatal startup errors prevent insecure deployments, while structured API responses and a user-friendly UI give administrators clear, actionable feedback. For public redirects, the system prioritizes graceful failure and provides transparent debugging cues through its fallback mechanism and placeholder-preserving behavior. This comprehensive strategy ensures the service is both robust for end-users and easy to manage and debug for administrators.