#883·falcor

Inconsistent error responses from `call` routes

Author: jmerrifieldCreated Sep 16, 2017Updated Oct 24, 2017

The error response when invoking call functions which throw appears to different depending on the data source in use, and whether running in the browser or under Node.js.

Given the following call usage:

javascript
// router
{
  route: 'login',
  call(callPath, [credentials]) {
    const err = new ForbiddenError('Some message');
    err.extraData = { someKey: 'someVal' };

    return Promise.reject(err);
  },
};

// app code
model.call('login', [{ email: '[email protected]', password: 'wrongpass' }], ['display_name']).then(
  r => console.log('*** success', r),
  err => { /* examine err */}
);

Using a model with an HttpDataSource in the browser (Chrome 62):

javascript
const model = new falcor.Model({
  // Note that the Express app hosting the `falcor-express` instance has error-handling
  // middleware returning a JSON representation of the error
  source: new HttpDataSource('http://localhost:3000/model.json')
});

// Prints:
// *** err instanceof Error: true
// *** err.message: "[object Object]"

Using a model with an HttpDataSource under Node.js (v6.11.1):

javascript
const model = new falcor.Model({
  source: new HttpDataSource('http://localhost:3000/model.json')
});

// Prints:
// *** err instanceof Error: true
// *** err.message: [JSON stringified version of the full error object]

Using a model with the router itself as a datasource under Node.js:

javascript
const model = new falcor.Model({
  source: myFalcorRouter
});

// err.name: 'Forbidden'
// err.extraData: { someKey: 'someVal' }

There seems to be a slight inconsistency in error handling between the way HttpDataSource handles JSON error responses in the browser vs. on Node.js. Additionally using the router directly as a data source has entirely different behavior (which couldn't be replicated over an HTTP interface unless we could guarantee the availability of any custom error subclasses on the client).

I'm left with a few questions:

  1. Are there plans for a consistent error representation that is datasource-independent, so that application code can handle errors without needing to know the specifics of how the model is wired to the router?
  2. What is the recommended method for propagating actionable/user-facing errors from call operations to consumers of the Model? For example: 'email already in use' while calling signup or 'invalid password' when calling login