Work in progress on a React-based error reporting mechanism.

The idea is that REST handlers always fail with throwing an Error (subclass of InteroperableError). The InteroperableError contains type and data field which are JSON-serialized and sent to client. It's up to the client to interpret the error and choose an appropriate way to present it.
This commit is contained in:
Tomas Bures 2017-06-05 00:52:59 +02:00
parent 4504d539c5
commit 79ea9e1897
10 changed files with 304 additions and 142 deletions

View file

@ -1,11 +0,0 @@
'use strict';
class InteroperableError extends Error {
constructor(type, msg, data) {
super(msg);
this.type = type;
this.data = data;
}
}
module.exports = InteroperableError;

View file

@ -0,0 +1,21 @@
'use strict';
class InteroperableError extends Error {
constructor(type, msg, data) {
super(msg);
this.type = type;
this.data = data;
}
}
class NotLoggedInError extends InteroperableError {
constructor(msg, data) {
super('NotLoggedIn', msg, data);
}
}
module.exports = {
InteroperableError,
NotLoggedInError
};

View file

@ -3,15 +3,15 @@
const knex = require('../knex');
const hasher = require('node-object-hash')();
const { filterObject } = require('../helpers');
const InteroperableError = require('../InteroperableError');
const interoperableErrors = require('../interoperable-errors');
class ChangedError extends InteroperableError {
class ChangedError extends interoperableErrors.InteroperableError {
constructor(msg, data) {
super('namespaces.ChangedError', msg, data);
}
}
class NotFoundError extends InteroperableError {
class NotFoundError extends interoperableErrors.InteroperableError {
constructor(msg, data) {
super('namespaces.NotFoundError', msg, data);
}

View file

@ -1,28 +1,10 @@
'use strict';
const express = require('express');
const InteroperableError = require('./InteroperableError');
function safeHandler(handler) {
return function(req, res) {
handler(req, res).catch(error => res.status(500).send(error.message));
};
}
function safeJSONHandler(handler) {
return function(req, res) {
handler(req, res).catch(error => {
const resp = {
message: error.message
};
if (error instanceof InteroperableError) {
resp.type = error.type;
resp.data = error.data;
}
res.status(500).json(resp);
});
function safeAsyncHandler(handler) {
return function(req, res, next) {
handler(req, res).catch(error => next(error));
};
}
@ -42,12 +24,10 @@ function replaceLast(elems, replaceFn) {
function create() {
const router = new express.Router();
router.getAsync = (path, ...handlers) => router.get(path, ...replaceLast(handlers, safeHandler));
router.getAsyncJSON = (path, ...handlers) => router.get(path, ...replaceLast(handlers, safeJSONHandler));
router.postAsyncJSON = (path, ...handlers) => router.post(path, ...replaceLast(handlers, safeJSONHandler));
router.putAsyncJSON = (path, ...handlers) => router.put(path, ...replaceLast(handlers, safeJSONHandler));
router.deleteAsyncJSON = (path, ...handlers) => router.delete(path, ...replaceLast(handlers, safeJSONHandler));
router.getAsync = (path, ...handlers) => router.get(path, ...replaceLast(handlers, safeAsyncHandler));
router.postAsync = (path, ...handlers) => router.post(path, ...replaceLast(handlers, safeAsyncHandler));
router.putAsync = (path, ...handlers) => router.put(path, ...replaceLast(handlers, safeAsyncHandler));
router.deleteAsync = (path, ...handlers) => router.delete(path, ...replaceLast(handlers, safeAsyncHandler));
return router;
}