moleculerjs / moleculer-web

:earth_africa: Official API Gateway service for Moleculer framework
http://moleculer.services/docs/moleculer-web.html
MIT License
294 stars 118 forks source link

Promise rejected with MoleculerError leads to request failure #80

Closed indigokidsgames closed 6 years ago

indigokidsgames commented 6 years ago

Env:

What happens:

Service action call is rejected with MoleculerError but Moleculer is sending fallback response as an outcome of failed request.

Desired outcome:

Moleculer should redirect exact API error to consumer.

Reproducing:

  1. Run following code (node.js):
const { ServiceBroker, Errors } = require('moleculer')
const ApiService = require('moleculer-web')

const broker = new ServiceBroker({
    logger: true,
    transporter: 'NATS',
})

broker.createService({
    name: 'api',
    mixins: [ApiService],

    settings: {
        routes: [
            {
                path: '',

                aliases: {
                    'GET test': 'testService.testAction',
                },

                bodyParsers: {
                    json: true,
                },

                mappingPolicy: 'restrict',

                callOptions: {
                    timeout: 10000,
                    retryCount: 10,
                    fallbackResponse: {
                        message: 'API Service Timed Out (fallback response)',
                    },
                },
            },
        ],

        // Global error handler
        onError(req, res, err) {
            console.error('console.error', err)
            res.writeHead(err.code || 500)
            res.end(JSON.stringify(err))
        },
    },
})

broker.createService({
    name: 'testService',

    /**
     * Actions
     */
    actions: {
        async testAction(ctx) {
            if (ctx.params.foo) {
                return { bar: void 0 }
            }

            throw new Errors.MoleculerError('ERR_DEMO_ERROR', 400)
        },
    },
})

broker.start().catch(err => {
    throw err
})
  1. Open http://localhost:3000/test in your browser
2018-10-08 19 01 22
[2018-10-08T16:09:56.540Z] INFO  pses-macbook-pro.local-22180/BROKER: Moleculer v0.13.3 is starting...
[2018-10-08T16:09:56.543Z] INFO  pses-macbook-pro.local-22180/BROKER: Node ID: pses-macbook-pro.local-22180
[2018-10-08T16:09:56.543Z] INFO  pses-macbook-pro.local-22180/BROKER: Namespace: <not defined>
[2018-10-08T16:09:56.543Z] INFO  pses-macbook-pro.local-22180/REGISTRY: Strategy: RoundRobinStrategy
[2018-10-08T16:09:56.545Z] INFO  pses-macbook-pro.local-22180/BROKER: Serializer: JSONSerializer
[2018-10-08T16:09:56.545Z] INFO  pses-macbook-pro.local-22180/BROKER: Transporter: NatsTransporter
[2018-10-08T16:09:56.546Z] INFO  pses-macbook-pro.local-22180/BROKER: Registered 10 internal middleware(s).
[2018-10-08T16:09:56.553Z] INFO  pses-macbook-pro.local-22180/API: Register route to ''
[2018-10-08T16:09:56.571Z] INFO  pses-macbook-pro.local-22180/API:   Alias: GET /test -> testService.testAction
[2018-10-08T16:09:56.571Z] INFO  pses-macbook-pro.local-22180/API: API Gateway created!
[2018-10-08T16:09:56.574Z] INFO  pses-macbook-pro.local-22180/TRANSIT: Connecting to the transporter...
[2018-10-08T16:09:56.586Z] INFO  pses-macbook-pro.local-22180/TRANSPORTER: NATS client is connected.
[2018-10-08T16:09:57.094Z] INFO  pses-macbook-pro.local-22180/REGISTRY: '$node' service is registered.
[2018-10-08T16:09:57.095Z] INFO  pses-macbook-pro.local-22180/REGISTRY: 'api' service is registered.
[2018-10-08T16:09:57.095Z] INFO  pses-macbook-pro.local-22180/REGISTRY: 'testService' service is registered.
[2018-10-08T16:09:57.095Z] INFO  pses-macbook-pro.local-22180/BROKER: ServiceBroker with 3 service(s) is started successfully.
[2018-10-08T16:09:57.100Z] INFO  pses-macbook-pro.local-22180/API: API Gateway listening on http://0.0.0.0:3000
[2018-10-08T16:10:02.627Z] INFO  pses-macbook-pro.local-22180/API: => GET /test
[2018-10-08T16:10:02.630Z] INFO  pses-macbook-pro.local-22180/API:    Call 'testService.testAction' action
[2018-10-08T16:10:02.636Z] WARN  pses-macbook-pro.local-22180/BROKER: The 'testService.testAction' request is failed. Return fallback response. { requestID: null, err: 'ERR_DEMO_ERROR' }
[2018-10-08T16:10:02.640Z] INFO  pses-macbook-pro.local-22180/API: <= 200 GET /test [+13.037 ms]
[2018-10-08T16:10:02.640Z] INFO  pses-macbook-pro.local-22180/API:
[2018-10-08T16:10:02.859Z] INFO  pses-macbook-pro.local-22180/API: => GET /favicon.ico
console.error { NotFoundError: Not found
    at Service.send404 (/Volumes/010101/MASS/mass-microservices/node_modules/moleculer-web/src/index.js:669:29)
    at actions.rest.then.result (/Volumes/010101/MASS/mass-microservices/node_modules/moleculer-web/src/index.js:195:12)
    at tryCatcher (/Volumes/010101/MASS/mass-microservices/node_modules/moleculer/node_modules/bluebird/js/release/util.js:16:23)
    at Promise._settlePromiseFromHandler (/Volumes/010101/MASS/mass-microservices/node_modules/moleculer/node_modules/bluebird/js/release/promise.js:512:31)
    at Promise._settlePromise (/Volumes/010101/MASS/mass-microservices/node_modules/moleculer/node_modules/bluebird/js/release/promise.js:569:18)
    at Promise._settlePromise0 (/Volumes/010101/MASS/mass-microservices/node_modules/moleculer/node_modules/bluebird/js/release/promise.js:614:10)
    at Promise._settlePromises (/Volumes/010101/MASS/mass-microservices/node_modules/moleculer/node_modules/bluebird/js/release/promise.js:694:18)
    at _drainQueueStep (/Volumes/010101/MASS/mass-microservices/node_modules/moleculer/node_modules/bluebird/js/release/async.js:138:12)
    at _drainQueue (/Volumes/010101/MASS/mass-microservices/node_modules/moleculer/node_modules/bluebird/js/release/async.js:131:9)
    at Async._drainQueues (/Volumes/010101/MASS/mass-microservices/node_modules/moleculer/node_modules/bluebird/js/release/async.js:147:5)
    at Immediate.Async.drainQueues (/Volumes/010101/MASS/mass-microservices/node_modules/moleculer/node_modules/bluebird/js/release/async.js:17:14)
    at runCallback (timers.js:810:20)
    at tryOnImmediate (timers.js:768:5)
    at processImmediate [as _immediateCallback] (timers.js:745:5)
  code: 404,
  type: 'NOT_FOUND',
  data: undefined,
  retryable: false }
indigokidsgames commented 6 years ago

So all I've had to do is remove fallbackResponse property and global error handler for it to work as desired. Turns out I didn't understood what request failure meant.