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 ?
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