Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hapijs Custom 500 Error Page

Looking through Hapi's documentation, and trying to google, I can find how to setup a 404 page, but I cannot find anything about setting up a 500 page.

I tried adding an error handler like follows:

server.on('internalError', function (request, err) {
    console.log("Internal Error:", err);
    request.reply.view('errors/500', {
        error: err
    }).code(500);
});

But my hook never gets called. Is there an easy way to return a custom 500 page with Hapijs?

like image 474
Mitchell Lee Avatar asked Aug 24 '15 14:08

Mitchell Lee


1 Answers

You need to trap the error response inside an onPreResponse extension function and set a new HTML response there.

The same principle applies to any Boom error, whether it be one set by you in a handler or set by hapi internally (e.g. a 404 Not found or a 401 Unauthorized from failed auth.

Here's an example that you can try yourself:

index.js

const Hapi = require('hapi');
const Path = require('path');

const server = new Hapi.Server();
server.connection({ port: 4000 });

server.route({
    method: 'GET',
    path: '/',
    handler: function (request, reply) {

        reply(new Error('I\'ll be a 500'));
    }
});

server.ext('onPreResponse', (request, reply) => {

    if (request.response.isBoom) {
        const err = request.response;
        const errName = err.output.payload.error;
        const statusCode = err.output.payload.statusCode;

        return reply.view('error', {
            statusCode: statusCode,
            errName: errName
        })
        .code(statusCode);
    }

    reply.continue();
});


server.register(require('vision'), (err) => {

    if (err) {
        throw err;
    }

    server.views({
        engines: {
            hbs: require('handlebars')
        },
        path: Path.join(__dirname, 'templates')
    });

    server.start((err) => {

        if (err) {
            throw err;
        }

        console.log('Server running at:', server.info.uri);
    });
});

templates/error.hbs

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{{title}}</title>

    <style>
        body {
            text-align: center;
            background: #B0B0B0;
            color: #222;
        }
        .error h1 {
            font-size: 80px;
            margin-bottom: 0;
        }
    </style>
</head>
<body>
    <div class="error">
        <h1>&#x26a0;<br/>{{statusCode}}</h1>
        <h2>{{errName}}</h2>
    </div>
</body>
</html>

Test it out by going to http://localhost:4000/ to see your custom error page:

enter image description here

This approach catches any Boom response, including those generated internally by hapi rather than by us. Therefore will also work with 4xx errors. Try navigating to http://localhost:4000/notapage and you'll get the same pretty page but for a 404:

enter image description here

like image 109
Matt Harrison Avatar answered Oct 29 '22 20:10

Matt Harrison