Seems that hierarchical error handling works..

TreeTable component seems to work too.
Edit is half-way through. Create / delete are TBD.
This commit is contained in:
Tomas Bures 2017-06-05 23:59:08 +02:00
parent 79ea9e1897
commit 5e4c86f626
24 changed files with 9967 additions and 261 deletions

View file

@ -24,7 +24,8 @@ module.exports = {
filterCustomFields,
getMjmlTemplate,
rollbackAndReleaseConnection,
filterObject
filterObject,
enforce
};
function getDefaultMergeTags(callback) {
@ -305,3 +306,10 @@ function filterObject(obj, allowedKeys) {
return result;
}
function enforce(condition, message) {
console.log(condition);
if (!condition) {
throw new Error(message);
}
}

View file

@ -1,21 +0,0 @@
'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

@ -2,20 +2,8 @@
const knex = require('../knex');
const hasher = require('node-object-hash')();
const { filterObject } = require('../helpers');
const interoperableErrors = require('../interoperable-errors');
class ChangedError extends interoperableErrors.InteroperableError {
constructor(msg, data) {
super('namespaces.ChangedError', msg, data);
}
}
class NotFoundError extends interoperableErrors.InteroperableError {
constructor(msg, data) {
super('namespaces.NotFoundError', msg, data);
}
}
const { enforce, filterObject } = require('../helpers');
const interoperableErrors = require('../../shared/interoperable-errors');
const allowedKeys = new Set(['id', 'name', 'description', 'parent']);
const allowedUpdateKeys = new Set(['name', 'description', 'parent']);
@ -31,7 +19,7 @@ function hash(ns) {
async function getById(nsId) {
const ns = await knex('namespaces').where('id', nsId).first();
if (!ns) {
throw new NotFoundError();
throw new interoperableErrors.NotFoundError();
}
ns.hash = hash(ns);
@ -45,18 +33,20 @@ async function create(ns) {
}
async function updateWithConsistencyCheck(ns) {
enforce(ns.id !== 1 || ns.parent === null, 'Cannot assign a parent to the root namespace.');
await knex.transaction(async tx => {
const existingNs = await tx('namespaces').where('id', ns.id).first();
if (!ns) {
throw new NotFoundError();
throw new interoperableErrors.NotFoundError();
}
const existingNsHash = hash(existingNs);
if (existingNsHash != ns.originalHash) {
throw new ChangedError();
throw new interoperableErrors.ChangedError();
}
tx('namespaces').where('id', ns.id).update(filterObject(ns, allowedUpdateKeys));
await tx('namespaces').where('id', ns.id).update(filterObject(ns, allowedUpdateKeys));
});
}
@ -65,8 +55,6 @@ async function remove(nsId) {
}
module.exports = {
NotFoundError,
ChangedError,
hash,
list,
getById,

View file

@ -2,32 +2,24 @@
const express = require('express');
function safeAsyncHandler(handler) {
return function(req, res, next) {
handler(req, res).catch(error => next(error));
};
}
function replaceLast(elems, replaceFn) {
if (elems.length === 0) {
return elems;
function replaceLastBySafeHandler(handlers) {
if (handlers.length === 0) {
return [];
}
const lastElem = elems[elems.size - 1];
const replacement = replaceFn(lastElem);
elems[elems.size - 1] = replacement;
return elems;
const lastHandler = handlers[handlers.length - 1];
const ret = handlers.slice();
ret[handlers.length - 1] = (req, res, next) => lastHandler(req, res).catch(error => next(error));
return ret;
}
function create() {
const router = new express.Router();
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));
router.getAsync = (path, ...handlers) => router.get(path, ...replaceLastBySafeHandler(handlers));
router.postAsync = (path, ...handlers) => router.post(path, ...replaceLastBySafeHandler(handlers));
router.putAsync = (path, ...handlers) => router.put(path, ...replaceLastBySafeHandler(handlers));
router.deleteAsync = (path, ...handlers) => router.delete(path, ...replaceLastBySafeHandler(handlers));
return router;
}