Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hapi error: handler method did not return a value, a promise, or thrown an error

I have a NodeJS application using Hapi on version 17 which consumes a web service which returns an image of a map, however, when run the code below I get the following error:

Debug: internal, implementation, error
    Error: handler method did not return a value, a promise, or throw an error
    at module.exports.internals.Manager.execute (C:\map\node_modules\hapi\lib\toolkit.js:52:29)
    at <anonymous>
    at process._tickCallback (internal/process/next_tick.js:188:7)

var Hapi = require('hapi'),
server = new Hapi.Server({
    host: '0.0.0.0',
    port: 8080,
    routes: {
        cors: true
    },
    SphericalMercator = require('sphericalmercator'),
    sm = new SphericalMercator({ size: 256 }),
    prequest = require('request').defaults({ encoding = null });

var wmsUrl = "http://localhost:8088/service/wms?SERVICE=WMS&REQUEST=GetMap&VERSION=1.1.1&STYLES=&FORMAT=image%2Fpng&HEIGHT=383&WIDTH=768&SRS=EPSG%3A3857";

server.route({
    method: 'GET',
    path: '/{layers}/{z}/{x}/{y}.png',
    handler: async (request, h) => {
        var bbox = sm.bbox(request.params., request.params.y, request.params.z, false, '00000');
        var theUrl = `${wmsUrl}&BBOX=${bbox.join(',')}&LAYERS=${decodeURIComponent(request.params.layers)}`;
        prequest.get(theUrl, function (err, res, body) {
            h.response(body).header('Cache-Control'), 'public, max-age=2629000').header('Content-Type', 'image/png');
        });
    }
});

server.start();

What am I doing wrong?

I'm writing this in the phone as the PC I'm working with right now, has no internet access, if I missed something or misspelled anything because of auto corrector, feel free to point it and I'll edit it to correct it.

like image 642
Frakcool Avatar asked Dec 24 '22 09:12

Frakcool


1 Answers

If you look at the hapi docs for lifecycle methods it states:

Each lifecycle method must return a value or a promise that resolves into a value.

So, just return something in your handler:

 handler: async (request, h) => {
        var bbox = sm.bbox(request.params., request.params.y, request.params.z, false, '00000');
        var theUrl = `${wmsUrl}&BBOX=${bbox.join(',')}&LAYERS=${decodeURIComponent(request.params.layers)}`;
        prequest.get(theUrl, function (err, res, body) {
            h.response(body).header('Cache-Control'), 'public, max-age=2629000').header('Content-Type', 'image/png');
        });

        return null; // or a Plain Value: string, number, boolean. Could be a Promise etc, more on the link above.
    }

If you don't return anything it would be undefined which it doesn't like.

EDIT:

If you want to return the body result from prequest, you can wrap it in a Promise and return it:

handler: async (request, h) => {
    ...

    const promise = new Promise((resolve, reject) => {
        prequest.get(theUrl, function (err, res, body) {
            if (err) {
                reject(err);
            } else {
                const response = h.response(body)
                    .header('Cache-Control', 'public, max-age=2629000')
                    .header('Content-Type', 'image/png');

                resolve(response);
            }

        });
    });

    return promise;
}
like image 66
Daniel Conde Marin Avatar answered May 18 '23 22:05

Daniel Conde Marin