Search code examples
javascriptnode.jsexpressloopback

Send Response back in Loopback on remote method beforeRemote hook


I am using loopback v3 for my application My use case is to validate if some token present in request header and if token is invalid then send appropriate message which is in standard format. I am trying to do that using beforeRemote.

What I have tried is to return promise reject when the token is invalid and the response is formatted through custom middleware(using express res object), I am able to do that. When I do that I am getting promise unhandled rejection warning,seems like Loopback is not handling the promise rejection. Is there a better way to handle the use case.

Module_Name.beforeRemote("*", async function(ctx, modelInst, next) {

let token = getTokenFromHeader(ctx.req.headers);
let tokenValid = await helper.validateToken(token);

if (tokenValid){
 return Promise.reject({statusCode:401}); // will not continue 
} 
next(); // call respective remote method

});

Warning Shown

(node:17177) UnhandledPromiseRejectionWarning: Error: Callback was already called.

(node:17177) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)

I tried going through the document also, but no help there.


Solution

  • Try this :

    //instead of single astrick, use double astrick to handle methods of both prototype and non-prototype Module_Name.beforeRemote('*', function (ctx, modelInst, next) {

        let token = getTokenFromHeader(ctx.req.headers);
        helper.validateToken(token).then((validToken) => {
            //for success, proceed with next()
            next();
        }, (invalidToken) => {
            next(throwError());
        }).catch((ex) => {
            next(throwError());
        });
    
        function throwError() {
            let error = new Error();
            error.statusCode = 401;
            error.message = "Invalid Token"
            return error;
        }
    });