最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to avoid Hapi.js sending 400 error when Validating Request with Joi - Stack Overflow

programmeradmin5浏览0评论

Hapi.js Validation with Joi + failAction question.

Situation

We want to build a "traditional" server-side-only rendered application using Hapi.

I'm trying to understand how to avoid returning a "raw" 400 error to the client when Joi validation fails:

We want to intercept this "email not allowed to be empty" validation error and display it in the html template back to the client, instead of simply returning the 400 error.

@AdriVanHoudt advised that we should:

"Look at failAction under "

So we added failAction: 'log' to the /register route handler:

{
  method: '*',
  path: '/register',
  config: {
    validate: {
      payload : register_fields,
      failAction: 'log'
    }
  },
  handler: register_handler
}

See code in: server.js

the register_handler is:

function register_handler(request, reply, source, error) {
  console.log(request.payload);
  console.log(' - - - - - - - - - - - - - - - - - - - - -');
  console.log(source)
  console.log(' - - - - - - - - - - - - - - - - - - - - -');
  console.log(error)
  return reply('wele!');
}

I am expecting to see an error in the terminal/console but when I try to console.log the handler :

- - - - - - - - - - - - - - - - - - - - -
undefined
- - - - - - - - - - - - - - - - - - - - -
undefined

I asked the question on GitHub: but have not yet got an answer with a good example. Full code if you have time to help:

Hapi.js Validation with Joi + failAction question.

Situation

We want to build a "traditional" server-side-only rendered application using Hapi.

I'm trying to understand how to avoid returning a "raw" 400 error to the client when Joi validation fails:

We want to intercept this "email not allowed to be empty" validation error and display it in the html template back to the client, instead of simply returning the 400 error.

@AdriVanHoudt advised that we should:

"Look at failAction under http://hapijs./api#route-options "

So we added failAction: 'log' to the /register route handler:

{
  method: '*',
  path: '/register',
  config: {
    validate: {
      payload : register_fields,
      failAction: 'log'
    }
  },
  handler: register_handler
}

See code in: server.js

the register_handler is:

function register_handler(request, reply, source, error) {
  console.log(request.payload);
  console.log(' - - - - - - - - - - - - - - - - - - - - -');
  console.log(source)
  console.log(' - - - - - - - - - - - - - - - - - - - - -');
  console.log(error)
  return reply('wele!');
}

I am expecting to see an error in the terminal/console but when I try to console.log the handler :

- - - - - - - - - - - - - - - - - - - - -
undefined
- - - - - - - - - - - - - - - - - - - - -
undefined

I asked the question on GitHub: https://github./hapijs/joi/issues/725 but have not yet got an answer with a good example. Full code if you have time to help: https://github./nelsonic/hapi-validation-question

Share Improve this question asked Oct 1, 2015 at 22:18 nelsonicnelsonic 33.2k21 gold badges95 silver badges124 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 11

There are Two Simple Solutions:

1. Use server.ext('onPreResponse' ...

As noted by @Clarkie a generic way of catching all errors in your Hapi App is to use 'onPreResponse'.

We wrote a Hapi Plugin that does exactly that: https://www.npmjs./package/hapi-error

As usual it has:

And lets you define your own custom error pages in 3 easy steps.

1. Install the plugin from npm:

npm install hapi-error --save

2. Include the plugin in your Hapi project

Include the plugin when you register your server:

See: /example/server_example.js for simple example

3. Ensure that you have a View called error_template

Note: hapi-error plugin expects you are using Vision (the standard view rendering library for Hapi apps) which allows you to use Handlebars, Jade, React, etc. for your templates.

Your error_template.html (or error_template.ext error_template.jsx) should make use of the 3 variables it will be passed:

  • errorTitle - the error tile generated by Hapi
  • statusCode - *HTTP statusCode sent to the client e.g: 404 (not found)
  • errorMessage - the human-friendly error message

for an example see: /example/error_template.html

That's it!

2. Use failAction

We added failAction which re-uses the register_handler so that the registration-form.html is shown with any input validation error message (until it is submitted with valid data)

{
  method: '*',
  path: '/register',
  config: {
    validate: {
      payload : register_fields,
      failAction: register_handler // register_handler is dual-purpose (see below!)
    }
  },
  handler: register_handler
}

the register_handler is:

function register_handler(request, reply, source, error) {
  // show the registration form until its submitted correctly
  if(!request.payload || request.payload && error) {
    var errors, values; // return empty if not set.
    if(error && error.data) { // means the handler is dual-purpose
      errors = extract_validation_error(error); // the error field + message
      values = return_form_input_values(error); // avoid wiping form data
    }
    return reply.view('registration-form', {
      title  : 'Please Register ' + request.server.version,
      error  : errors, // error object used in html template
      values : values  // (escaped) values displayed in form inputs
    }).code(error ? 400 : 200); // HTTP status code depending on error
  }
  else { // once successful, show wele message!
    return reply.view('wele-message', {
      name   : validator.escape(request.payload.name),
      email  : validator.escape(request.payload.email)
    })
  }
}

See: server.js:57 for plete file.

Where extract_validation_error(error) and return_form_input_values(error) are helper functions defined within server.js (but would be split out into re-useable view helpers) which keep our handler function lean.

When we submit the form without any of the required fields we see:

We also use https://github./chriso/validator.js to mitigate Cross Site Scripting vulnerability:

And display a wele message on successful registration:

Conclusion

We feel that re-using the handler function as the failAction keeps the code related to this route/action in a single place whereas server.ext('onPreResponse' ... (while appropriate on initial inspection) will introduce "hooks" which can be a source of confusion (once an app has many such hooks...)

#YMMV

Let us know what you think!

You should look at implementing an error handler in the onPreResponse extension point.

The response contained in request.response may be modified (but not assigned a new value). To return a different response type (for example, replace an error with an HTML response), return a new response via reply(response). Note that any errors generated after reply(response) is called will not be passed back to the onPreResponse extension method to prevent an infinite loop.

A simple example:

server.ext('onPreResponse', function (request, reply) {
  if (request.response.statusCode === 400 ){
    return reply('summat else');
  }
  return reply.continue();
});
发布评论

评论列表(0)

  1. 暂无评论