-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Error Handler #4
Comments
Hey @davidbarratt - it's possible to do that, although a bit verbose (I might add a convenience wrapper for this in the future 😄) Here's a full example (Cloudflare Worker, TypeScript) how one might do NotFound and error handling with the router: import CloudflareWorkerGlobalScope from "types-cloudflare-worker"
declare var self: CloudflareWorkerGlobalScope
import { HandlerContext, Router } from "service-worker-router"
const ping = async () => new Response("pong")
const notFound = async () => new Response("Not found :(", { status: 404 })
const errorResponse = async (err: Error) => new Response(`Error occured: ${err.message}`)
const conditionalThrow = async ({ request, params }: HandlerContext): Promise<Response> => {
if (params.wish === "yes") {
throw new Error("I threw.")
}
return new Response("All good.", { status: 200 })
}
const router = new Router()
router.all("/_ping", ping)
router.all("/throw/:wish", conditionalThrow)
async function fetchEventHandler(event: FetchEvent): Promise<Response> {
try {
const match = router.handleRequest(event.request)
if (match) {
return await match.handlerPromise // await is important here for error catching to work
}
return notFound()
} catch (err) {
return errorResponse(err)
}
}
self.addEventListener("fetch", (event: FetchEvent) => {
event.respondWith(fetchEventHandler(event))
}) Results in: ❯ curl 'https://my-worker.com/_ping'
pong
❯ curl 'https://my-worker.com/foobar'
Not found :(
❯ curl 'https://my-worker.com/throw/nope'
All good.
❯ curl 'https://my-worker.com/throw/yes'
Error occured: I threw. |
Hi, I've been using this router and have had a similar wish: being able to easily handle errors, here the solution I came up with: // withErrorHandler.js
/**
* Higher order function providing generic error handling for request handlers
* @param {Function} func a request handler
* @returns {Response}
*/
export function withErrorHandler (func) {
return async function handler (...args) {
try {
// await is not superfluous here as otherwise the catch is bypassed
return await func(...args)
} catch (error) {
const url = new URL(args.request.url)
const debug = url.searchParams.get('debug') === 'true'
return debug // show the stack trace, could be used to send it to a monitoring system or else
? new Response(error.stack || error)
: new Response(null, { status: 500 })
}
}
} // index.js
import { Router } from 'service-worker-router'
import { routeHandler } from './routeHandler'
import { withErrorHandler } from './withErrorHandler'
const router = new Router()
router.get('/path/to/handle', withErrorHandler(routeHandler))
addEventListener('fetch', (event) => {
// Will test event.request against the defined routes
// and use event.respondWith(handler) when a route matches
return router.handleEvent(event)
}) Just sharing it in case it may help someone else. |
Is there a way to define an error handler? My handler may throw an exception and it would be nice to catch the exceptions from the handlers and handle them together.
The text was updated successfully, but these errors were encountered: