Edit Page

Custom responses

Overview

Sails apps come bundled with several pre-configured responses that can be called from action code. These default responses can handle situations like “resource not found” (the notFound response) and “internal server error” (the serverError response). If your app needs to modify the way that the default responses work, or create new responses altogether, you can do so by adding files to the api/responses folder.

Note: api/responses is not generated by default in new Sails apps, so you’ll have to add it yourself if you want to add / customize responses.

Using responses

As a quick example, consider the following action:

getProfile: function(req, res) {

  // Look up the currently logged-in user's record from the database.
  User.findOne({ id: req.session.userId }).exec(function(err, user) {
    if (err) {
      res.status(500);
      return res.view('500', {data: err});
    }

    return res.json(user);
  });
}

This code handles a database error by sending a 500 error status and sending the error data to a view to be displayed. However, this code has several drawbacks, primarily:

  • The response isn't content-negotiated: if the client is expecting a JSON response, they're out of luck
  • The response reveals too much about the error: in production, it'd be best to just log the error to the terminal
  • It isn't normalized: even if we dealt with the other bullet points above, the code is specific to this action, and we'd have to work hard to keep the exact same format for error handling everywhere
  • It isn't abstracted: if we wanted to use a similar approach elsewhere, we'd have to copy / paste the code

Now, consider this replacement:

getProfile: function(req, res) {

  // Look up the currently logged-in user's record from the database.
  User.findOne({ id: req.session.userId }).exec(function(err, user) {
    if (err) { return res.serverError(err); }
    return res.json(user);
  });
}

This approach has many advantages:

  • More concise
  • Error payloads are normalized
  • Production vs. development logging is taken into account
  • Error codes are consistent
  • Content negotiation (JSON vs HTML) is taken care of
  • API tweaks can be done in one quick edit to the appropriate generic response file

Response methods and files

Any .js file saved in the api/responses/ folder can be executed by calling res.thatFileName(). For example, api/responses/insufficientFunds.js can be executed with a call to res.insufficientFunds().

Accessing req, res, and sails

The request and response objects are available inside of a custom response as this.req and this.res. This allows the actual response function to take arbitrary parameters. For example:

return res.insufficientFunds(err, { happenedDuring: 'signup' });

And the implementation of the custom response might look something like this:

module.exports = function insufficientFunds(err, extraInfo){

  var req = this.req;
  var res = this.res;
  var sails = req._sails;

  var newError = new Error('Insufficient funds');
  newError.raw = err;
  _.extend(newError, extraInfo);

  sails.log.verbose('Sent "Insufficient funds" response.');

  return res.badRequest(newError);

}

Built-in responses

All Sails apps have several pre-configured responses like res.serverError() and res.notFound() that can be used even if they don’t have corresponding files in api/responses/.

Any of the default responses may be overridden by adding a file with the same name to api/responses/ in your app (e.g. api/responses/serverError.js).

You can use the Sails command-line tool as a shortcut for doing this.

For example:

sails generate response serverError

Is something missing?

If you notice something we've missed or could be improved on, please follow this link and submit a pull request to the sails repo. Once we merge it, the changes will be reflected on the website the next time it is deployed.

Sails logo
  • Home
  • Get started
  • Support
  • Documentation
  • Documentation

For a better experience on sailsjs.com, update your browser.

Check out the full Sailsconf 2022 playlist on Youtube

Tweet Follow @sailsjs

Documentation

Reference Concepts App structure | Upgrading Contribution guide | Tutorials More

Concepts

  • Actions and controllers
    • Generating actions and controllers
    • Routing to actions
  • Assets
    • Default tasks
    • Disabling Grunt
    • Task automation
  • Blueprints
    • Blueprint actions
    • Blueprint routes
  • Configuration
    • The local.js file
    • Using `.sailsrc` files
  • Deployment
    • FAQ
    • Hosting
    • Scaling
  • E-commerce
  • Extending Sails
    • Adapters
      • Available adapters
      • Custom adapters
    • Custom responses
      • Adding a custom response
    • Generators
      • Available generators
      • Custom generators
    • Hooks
      • Available hooks
      • Events
      • Hook specification
        • .configure
        • .defaults
        • .initialize()
        • .registerActions()
        • .routes
      • Installable hooks
      • Project hooks
      • Using hooks
  • File uploads
    • Uploading to GridFS
    • Uploading to S3
  • Globals
    • Disabling globals
  • Helpers
    • Example helper
  • Internationalization
    • Locales
    • Translating dynamic content
  • Logging
    • Custom log messages
  • Middleware
    • Conventional defaults
  • Models and ORM
    • Associations
      • Many-to-many
      • One way association
      • One-to-many
      • One-to-one
      • Reflexive associations
      • Through associations
    • Attributes
    • Errors
    • Lifecycle callbacks
    • Model settings
    • Models
    • Query language
    • Records
    • Standalone Waterline usage
    • Validations
  • Policies
    • Access Control and Permissions
  • Programmatic usage
    • Tips and tricks
  • Realtime
    • Multi-server environments
    • On the client
    • On the server
  • Routes
    • Custom routes
    • URL slugs
  • Security
    • Clickjacking
    • Content security policy
    • CORS
    • CSRF
    • DDOS
    • P3P
    • Socket hijacking
    • Strict Transport Security
    • XSS
  • Services
  • Sessions
  • Shell scripts
  • Testing
  • Views
    • Layouts
    • Locals
    • Partials
    • View engines

Built with Love

The Sails framework is built by a web & mobile shop in Austin, TX, with the help of our contributors. We created Sails in 2012 to assist us on Node.js projects. Naturally we open-sourced it. We hope it makes your life a little bit easier!

Sails:
  • What is Sails?
  • Community
  • News
  • For business
About:
  • Our company
  • Security
  • Legal
  • Logos/artwork
Help:
  • Get started
  • Documentation
  • Docs
  • Contribute
  • Take a class

© 2012-2023 The Sails Company. 
The Sails framework is free and open-source under the MIT License. 
Illustrations by Edamame.