Moleculer: Service scope middleware trouble

Created on 17 Jul 2018  路  15Comments  路  Source: moleculerjs/moleculer

After migrating moleculer to 0.13, my service scope middleware is not working correctly, of course I'v tried the middleware v2 but still same behavior.
What happened.
I have a middleware savec in service broker:

  // Register middlewares
  middlewares: [packControl()],

  // Called after broker created.
module.exports = () => (handler, action) => {
  return async (ctx) => {
    let pack = action.pack;
    if (!pack) //no check angainst ths action
    {
        return handler(ctx);
    }
    const packCheck = (typeof pack === 'function' ) ? await pack.call(action.service, ctx) : pack;
    if(!packCheck) return handler(ctx);
    const yes = await can(ctx, {
      workspace: ctx.meta.user.workspace,
      key: packCheck.key,
      check: packCheck.check
    });
    if (!yes) return Promise.reject(packCheck.message || '***********');
    return handler(ctx);
  }
}

The middleware worked great with old version, but now the Promise.reject is never returned I just see the promise rejection message in the console

Unhandled rejection MoleculerError: Les espace de travail de type client ne peuvent pas avoir plus de 2 membres
    at handler.catch.err (C:\Users\****\node_modules\moleculer\src\middlewares\error-handler.js:18:12)
    at <anonymous>

Am I missing something in my middleware ?

Need reproduce

All 15 comments

Could you make a repro repo?

I tried with it, but working fine.

"use strict";

const ServiceBroker = require("moleculer");

const mw = () => (handler, action) => {
    return async (ctx) => {
        return Promise.reject("Some error");
    };
};

const broker = new ServiceBroker({
    nodeID: "dev",
    middlewares: [mw()]
});

broker.createService({
    name: "test",
    actions: {

        hello(ctx) {
            return "Hello Moleculer";
        }
    }
});

broker.start()
    .then(() => broker.repl())
    .delay(1000)
    .then(() => broker.call("test.hello"))
    .then(res => broker.logger.info(res))
    .catch(err => broker.logger.error(err));

Obviously , I see just the throwed exception in console, but request stay without returns and finally fail , maybe a problem in moleculer-web ??

Yes, maybe issue is in API GW side. There are some similar opened issue in its repo (of course I can't reproduce them, as well)

I found the problem, it's indeed in moleculer-web at
https://github.com/moleculerjs/moleculer-web/blob/9c84d6bc45b0f904b0f5f7617cfa7240df409687/src/index.js#L455
where you throw the error occured, but that error is never handled.
When I add a catch on after calling callAction method all work fine like this
Line : https://github.com/moleculerjs/moleculer-web/blob/9c84d6bc45b0f904b0f5f7617cfa7240df409687/src/index.js#L381

return this.callAction(route, alias.action, req, res, req.$params)
.catch(err=>{
    if (err){
            this.sendError(req, res, err);
        }
});

Indeed when we dont use alias middleware all work perfectly, but one we use aliases middleaware, the problem appear

routes:[
    {
        path: '/',
        aliases:{
            "GET ": [
                (req,res, next)=>{console.log("Middleware");return next()},
                "web.welcome"
            ]
        }
    }
]
//Give the unhandling error
routes:[
    {
        path: '/',
        aliases:{
            "GET ": "web.welcome"
        }
    }
]
//work well

I think this catch case doesn't matter because of the this.callAction return a Promise and there is a catch in httpHandler:

https://github.com/moleculerjs/moleculer-web/blob/master/src/index.js#L200

But that catch block doesn't handle any error thrown in an action or by service scope middleware when we have an array of middlewares followed by the action as route alias.
Don't know why.

But your catch won't handle it, as well. The problem occurs when you use req.send to send the response back to the client in your middleware. In this case, the api.rest action call promise chain won't be resolved (because you don't call next), and it'll be timed out.

My middleware doesn't end the request (by calling req.send or something like this) so I don't think that cause the issue. I got the same behavior, by just throwing an exception an action.

In this case, please create a minimal repro repo, and I'll try to debug it.

Okay right now

Thx, I can reproduce

I found & fixed it. Please try it with npm i moleculerjs/moleculer-web --save

Work good now :)
Thank you

Was this page helpful?
0 / 5 - 0 ratings

Related issues

slinkardbrandon picture slinkardbrandon  路  4Comments

HighSoftWare96 picture HighSoftWare96  路  4Comments

abdavid picture abdavid  路  4Comments

Kamil93 picture Kamil93  路  3Comments

demetriusnunes picture demetriusnunes  路  5Comments