【问题标题】:Hapijs Custom 500 Error PageHapijs 自定义 500 错误页面
【发布时间】:2015-11-18 00:30:02
【问题描述】:

查看 Hapi 的文档,并尝试 google,我可以找到如何设置 404 页面,但我找不到任何关于设置 500 页面的信息。

我尝试添加如下错误处理程序:

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

但我的钩子永远不会被调用。有没有一种简单的方法可以使用 Hapijs 返回自定义 500 页面?

【问题讨论】:

    标签: node.js hapijs


    【解决方案1】:

    您需要在 onPreResponse 扩展函数中捕获错误响应并在那里设置新的 HTML 响应。

    同样的原则适用于任何 Boom 错误,无论是您在处理程序中设置的错误还是 hapi 内部设置的错误(例如,404 Not found 或 401 Unauthorized from failed auth。

    这是一个您可以自己尝试的示例:

    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);
        });
    });
    

    模板/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>
    

    转到http://localhost:4000/ 以查看您的自定义错误页面进行测试:

    这种方法可以捕获任何 Boom 响应,包括那些由 hapi 而不是我们内部生成的响应。因此也适用于 4xx 错误。尝试导航到http://localhost:4000/notapage,您将获得相同的漂亮页面,但显示的是 404:

    【讨论】:

    • 太棒了,感谢您写得很好的答案。我会在几分钟后尝试这个并标记为答案。
    • 我怎样才能让它与hapi一起工作。它无法识别.continue();
    【解决方案2】:

    对于那些寻找与 Hapi v17+ 兼容的答案的人,相同的代码 index.js 代码将被翻译为:

    index.js

    "use strict";
    
    const hapi = require('hapi');
    const path = require('path');
    
    const server = new hapi.Server({ port: 4000 });
    
    server.route({
        method: 'GET',
        path: '/',
        handler: (request, h) {
            return new Error('I\'ll be a 500');
        }
    });
    
    server.ext({
        type: 'onPreResponse',
        method: (request, h) => {
    
            if (request.response.isBoom) {
                const err = request.response;
                const errName = err.output.payload.error;
                const statusCode = err.output.payload.statusCode;
    
                return h.view('error', {
                    statusCode: statusCode,
                    errName: errName
                })
                .code(statusCode);
            }
    
            return h.continue;
        }
    });
    
    
    (async()=>{
    
        await server.register([ require('@hapi/vision') ]);
    
        server.views({
            engines: { hbs: require('handlebars') },
            path: Path.join(__dirname, 'templates')
        });
    
        await server.start();
    
        return `Server running at: ${server.info.uri}`;
    
    })().then(console.log).catch(console.error);
    
    

    【讨论】:

      猜你喜欢
      • 2015-08-26
      • 2019-01-18
      • 2011-02-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多