GitHub GitHub
docs / Error Handling

Error Handling

LiteNode provides two dedicated hooks for handling errors: onError for uncaught runtime errors and notFound for 404 responses.

onError

Signature:

onError(handler: (err, req, res) => void): LiteNode

Defines a custom handler for uncaught internal server errors. Receives the error object alongside the standard req and res.

app.onError(async (err, req, res) => {
    console.error(err)
    res.status(500).json({ error: "Internal Server Error" })
})

You can inspect the error and respond differently based on its type:

app.onError(async (err, req, res) => {
    if (err.type === "unauthorized") {
        return res.status(401).json({ error: "Unauthorized" })
    }
    if (err.type === "not_found") {
        return res.status(404).html("<h1>Not Found</h1>")
    }
    res.status(500).html("<h1>Something went wrong</h1>")
})

notFound

Signature:

notFound(handler: RouteHandler): LiteNode

Defines a handler for requests that match no registered route (404).

app.notFound(async (req, res) => {
    res.status(404).render("layouts/404.html", {
        title: "Page Not Found",
    })
})

Route-Level Error Handling

For errors you can anticipate inside a route, use a standard try/catch:

app.get("/posts/:slug", async (req, res) => {
    try {
        const post = await db.getPost(req.params.slug)
        if (!post) return res.status(404).json({ error: "Post not found" })
        res.json(post)
    } catch (err) {
        res.status(500).json({ error: err.message })
    }
})

Registration Order

Register both onError and notFound before calling startServer(), typically at the top of your route file:

app.onError(async (err, req, res) => {
    /* ... */
})
app.notFound(async (req, res) => {
    /* ... */
})

app.get("/", (req, res) => {
    /* ... */
})

app.startServer()