hemerajs / aither

An example microservice system in Node.js using Hemera and best of today.
GNU General Public License v3.0
119 stars 26 forks source link

Joi validation not working? #2

Closed ggn06awu closed 7 years ago

ggn06awu commented 7 years ago

I've just run this example, but the validation described in the Hemera documentation as used here, doesn't appear to have the desired effect.

Input Requested URL: http://localhost:8182/api/add?a=2&b=52ca

Expected Result Some form of error given back to the actor where err instanceOf PayloadValidationError

Actual Result math-service/index.js:35 let operation = (a, b) => { return a + b }

This routine is still executed, where typeof a === 'string', so the values are concatenated.

Is there a bug / change in the Joi validator breaking this example?

StarpTech commented 7 years ago

Hi @ggn06awu thanks. I forgot to activate the validator with

// Use Joi as payload validator
hemera.setOption('payloadValidator', 'hemera-joi')

I think about to enable it by default. I also updated all dependencies to the latest version. Please try again and don't forget to rebuild your environment with:

docker-compose build --no-cache
docker-compose up
ggn06awu commented 7 years ago

Thanks @StarpTech, that certainly appears to have done the job!

Out of curiosity, when entering a non-numeric value it brings down the API service, is that related (and intentional) when wrapping the error response in Boom? Logs :-

api_1 | { PreValidationError api_1 | at Joi.validate (/usr/src/app/node_modules/hemera-joi/index.js:38:18) api_1 | at Object._validateWithOptions (/usr/src/app/node_modules/joi/lib/types/any/index.js:654:20) api_1 | at Object.root.validate (/usr/src/app/node_modules/joi/lib/index.js:121:23) api_1 | at Hemera. (/usr/src/app/node_modules/hemera-joi/index.js:33:9) api_1 | at each (/usr/src/app/node_modules/nats-hemera/lib/extension.js:82:14) api_1 | at iterate (/usr/src/app/node_modules/nats-hemera/lib/util.js:128:9) api_1 | at done (/usr/src/app/node_modules/nats-hemera/lib/util.js:121:15) api_1 | at Hemera.onServerPreHandler (/usr/src/app/node_modules/nats-hemera/lib/extensions.js:222:3) api_1 | at each (/usr/src/app/node_modules/nats-hemera/lib/extension.js:82:14) api_1 | at iterate (/usr/src/app/node_modules/nats-hemera/lib/util.js:128:9) api_1 | name: 'PreValidationError', api_1 | message: 'child "b" fails because ["b" must be a number]', api_1 | stack: 'PreValidationError\n at Joi.validate (/usr/src/app/node_modules/hemera-joi/index.js:38:18)\n at Object._validateWithOptions (/usr/src/app/node_modules/joi/lib/types/any/index.js:654:20)\n at Object.root.validate (/usr/src/app/node_modules/joi/lib/index.js:121:23)\n at Hemera. (/usr/src/app/node_modules/hemera-joi/index.js:33:9)\n at each (/usr/src/app/node_modules/nats-hemera/lib/extension.js:82:14)\n at iterate (/usr/src/app/node_modules/nats-hemera/lib/util.js:128:9)\n at done (/usr/src/app/node_modules/nats-hemera/lib/util.js:121:15)\n at Hemera.onServerPreHandler (/usr/src/app/node_modules/nats-hemera/lib/extensions.js:222:3)\n at each (/usr/src/app/node_modules/nats-hemera/lib/extension.js:82:14)\n at iterate (/usr/src/app/node_modules/nats-hemera/lib/util.js:128:9)', api_1 | details: api_1 | [ { message: '"b" must be a number', api_1 | path: 'b', api_1 | type: 'number.base', api_1 | context: [Object] } ] } traefik_1 | time="2017-06-11T16:25:34Z" level=warning msg="Error forwarding to http://172.18.0.11:8789, err: EOF" traefik_1 | time="2017-06-11T16:25:34Z" level=debug msg="Provider event received {Status:die ID:baa47df0f72a0329bb04f5f0af69a92ae0b0db4ec931cb693865c3688cc49656 From:aither_api Type:container Action:die Actor:{ID:baa47df0f72a0329bb04f5f0af69a92ae0b0db4ec931cb693865c3688cc49656 Attributes:map[com.docker.compose.version:1.8.0 exitCode:1 image:aither_api traefik.backend:api traefik.frontend.entryPoints:http traefik.frontend.rule:PathPrefix: /api com.docker.compose.config-hash:aa74fbb726696cd97f98241f8b9f6018105ef9363babc42dab9a0fc3b124ab4a com.docker.compose.project:aither traefik.port:8789 com.docker.compose.service:api name:aither_api_1 com.docker.compose.container-number:1 com.docker.compose.oneoff:False]} Time:1497198334 TimeNano:1497198334925231325}" aither_api_1 exited with code 1

StarpTech commented 7 years ago

@ggn06awu what do you mean "brings down the API service" ? It violates against the validation schema and will response with an error but the api should be still available. Please post your logic.

ggn06awu commented 7 years ago

Running the code as it is now, calling with a non-numeric argument actually causes the api process to exit, aither_api_1 exited with code 1. In testing terms:

Scenario 1: Input Repetitive simple well formed addition calls, e.g.: http://localhost:8182/api/add?a=2&b=4

Scenario 1: Expected Response

6

Scenario 1: Actual Response

6 (OK)

Scenario 2: Input Repetitive malformed formed addition calls, e.g.: http://localhost:8182/api/add?a=2&b=**zzz**

Scenario 2: Expected Response

Boom wrapped error response?

Scenario 2: Actual Response

Bad Gateway

Logs from traefik report the process exited with code 1, subsequent healthy requests also now fail as a result.

traefik_1 | time="2017-06-11T17:13:54Z" level=warning msg="Error forwarding to http://172.18.0.12:8789, err: EOF" traefik_1 | time="2017-06-11T17:13:54Z" level=debug msg="Provider event received {Status:die ID:94b5462c2c19584a198bd871688c1d487432086211ab1633a3c29fab32359150 From:aither_api Type:container Action:die Actor:{ID:94b5462c2c19584a198bd871688c1d487432086211ab1633a3c29fab32359150 Attributes:map[com.docker.compose.version:1.8.0 exitCode:1 image:aither_api traefik.backend:api traefik.frontend.entryPoints:http traefik.frontend.rule:PathPrefix: /api com.docker.compose.container-number:1 com.docker.compose.project:aither com.docker.compose.service:api name:aither_api_1 traefik.port:8789 com.docker.compose.config-hash:1bd21bd59373d8a04b8f14c8f517529c0b7fb6296bcd6f5d87c041ede6daced8 com.docker.compose.oneoff:False]} Time:1497201234 TimeNano:1497201234433887646}" aither_api_1 exited with code 1

Logs from api

api_1 | { PreValidationError api_1 | at Joi.validate (/usr/src/app/node_modules/hemera-joi/index.js:38:18) api_1 | at Object._validateWithOptions (/usr/src/app/node_modules/joi/lib/types/any/index.js:654:20) api_1 | at Object.root.validate (/usr/src/app/node_modules/joi/lib/index.js:121:23) api_1 | at Hemera. (/usr/src/app/node_modules/hemera-joi/index.js:33:9) api_1 | at each (/usr/src/app/node_modules/nats-hemera/lib/extension.js:82:14) api_1 | at iterate (/usr/src/app/node_modules/nats-hemera/lib/util.js:128:9) api_1 | at done (/usr/src/app/node_modules/nats-hemera/lib/util.js:121:15) api_1 | at Hemera.onServerPreHandler (/usr/src/app/node_modules/nats-hemera/lib/extensions.js:222:3) api_1 | at each (/usr/src/app/node_modules/nats-hemera/lib/extension.js:82:14) api_1 | at iterate (/usr/src/app/node_modules/nats-hemera/lib/util.js:128:9) api_1 | name: 'PreValidationError', api_1 | message: 'child "b" fails because ["b" must be a number]', api_1 | stack: 'PreValidationError\n at Joi.validate (/usr/src/app/node_modules/hemera-joi/index.js:38:18)\n at Object._validateWithOptions (/usr/src/app/node_modules/joi/lib/types/any/index.js:654:20)\n at Object.root.validate (/usr/src/app/node_modules/joi/lib/index.js:121:23)\n at Hemera. (/usr/src/app/node_modules/hemera-joi/index.js:33:9)\n at each (/usr/src/app/node_modules/nats-hemera/lib/extension.js:82:14)\n at iterate (/usr/src/app/node_modules/nats-hemera/lib/util.js:128:9)\n at done (/usr/src/app/node_modules/nats-hemera/lib/util.js:121:15)\n at Hemera.onServerPreHandler (/usr/src/app/node_modules/nats-hemera/lib/extensions.js:222:3)\n at each (/usr/src/app/node_modules/nats-hemera/lib/extension.js:82:14)\n at iterate (/usr/src/app/node_modules/nats-hemera/lib/util.js:128:9)', api_1 | details: api_1 | [ { message: '"b" must be a number', api_1 | path: 'b', api_1 | type: 'number.base', api_1 | context: [Object] } ] }

Not sure what else to give!

StarpTech commented 7 years ago

I think I found the issue I still forgot to update some places after the hemera upgrade. If you look in the api gateway it want to wrap error.cause in boom error but there is no cause attribute. Use only the error and try again. I will check it out tonight thanks!

StarpTech commented 7 years ago

@ggn06awu I fixed it please pull and try again. You should see something like this

{"statusCode":400,"error":"Bad Request","message":"child \"b\" fails because [\"b\" must be a number]"}
ggn06awu commented 7 years ago

All good, thanks @StarpTech !