diff options
| author | Sean Fridman <fridman@mail.sfsu.edu> | 2015-04-13 13:42:11 -0400 |
|---|---|---|
| committer | Sean Fridman <fridman@mail.sfsu.edu> | 2015-04-13 13:42:11 -0400 |
| commit | 5b7e5a133e5326a98b974b7e9e390ac393d1a05e (patch) | |
| tree | 6a7fc0119f79b9467135fc0aac961e2409ddcbf0 /app/node_modules/okadminview/index.js | |
| parent | 741bb035e10a1d89dfaa60ab79d25a63d2ff4726 (diff) | |
Client friendly error handling
Diffstat (limited to 'app/node_modules/okadminview/index.js')
| -rw-r--r-- | app/node_modules/okadminview/index.js | 125 |
1 files changed, 55 insertions, 70 deletions
diff --git a/app/node_modules/okadminview/index.js b/app/node_modules/okadminview/index.js index 2f31e1e..648487c 100644 --- a/app/node_modules/okadminview/index.js +++ b/app/node_modules/okadminview/index.js @@ -37,6 +37,8 @@ function OKAdminView(options) { throw new Error('No templateProvider provided to OKAdminView'); if (!options.meta) throw new Error('No meta query provided to OKAdminView'); + if (!options.errorHandler) + throw new Error('No error handler provided to OKAdminView'); var app = options.app; var express = options.express; @@ -44,6 +46,7 @@ function OKAdminView(options) { var resourceCache = this._resourceCache = options.resourceCache; var resourceConfig = this._resourceConfig = cloneDeep(options.resourceConfig); var provider = options.templateProvider; + var error = this._error = options.errorHandler; // Load templates var templates = this._templates = @@ -112,12 +115,10 @@ function OKAdminView(options) { } })); - var auth = passport.authenticate('digest', {session: false}); - // This should really be mounted on the router, but can't be due to // https://github.com/jaredhanson/passport-http/pull/16 app.use('/admin/', passport.initialize()); - app.all('/admin/:path*', auth); + app.all('/admin/:path*', passport.authenticate('digest', {session: false})); router.get('/', function readIndex(req, res, next) { fetchIndexTemplateData(meta, indexQueries).then(function(data) { @@ -125,22 +126,22 @@ function OKAdminView(options) { success: req.flash('success'), errors: req.flash('errors') })); - }).fail(errorHandler(req, res)); + }).fail(error(req, res, 500)); }); router.get('/:type/new/', function createResourceView(req, res, next) { var type = req.params.type || ''; var resource = resourceCache.get(type); if (!resource) { - errorHandler(req, res)(new Error('No such resource ' + type)); + error(req, res, 404)(new Error('No such resource ' + type)); } else { meta.get().then(function(metadata) { - var templateData = getResourceTemplateData(metadata, resource, {}); + var templateData = transformData(metadata, resource, {}); view.renderResourceNew(req, res, assign(templateData, { success: req.flash('success'), errors: req.flash('errors'), })); - }).fail(errorHandler(req, res)); + }).fail(error(req, res, 500)); } }); @@ -148,26 +149,27 @@ function OKAdminView(options) { var type = req.params.type || ''; var id = req.params.id || ''; var resource = resourceCache.get(type, id); - if (!resource) { - errorHandler(req, res)(new Error('No such resource')); - } else { - var query = OKQuery({ - resource: resource, - query: id - }); - fetchResourceTemplateData(meta, query, getResourceTemplateData) - .then(function(data) { - if (!data) { - resourceMissingHandler(req, res)() - } else { - view.renderResource(req, res, assign(data, { - success: req.flash('success'), - errors: req.flash('errors') - })); - } - }).fail(errorHandler(req, res)); - } - + var query = OKQuery({ + resource: resource, + query: id + }); + fetchResourceTemplateData(meta, query, transformData) + .then(function(data) { + if (!data) { + resourceMissingHandler(req, res)() + } else { + view.renderResource(req, res, assign(data, { + success: req.flash('success'), + errors: req.flash('errors') + })); + } + }).fail(function(err) { + if (err.message === 'No resource data') { + error(req, res, 404)(new Error('No such resource')); + } else { + error(req, res, 500)(err); + } + }); }); router.post('/:type/', function createResource(req, res, next) { @@ -175,7 +177,7 @@ function OKAdminView(options) { var resource = resourceCache.get(type); var data = req.body; if (!resource) { - errorHandler(req, res)(new Error('No such resource ' + type)); + error(req, res, 400)(new Error('No such resource ' + type)); } else { meta.get().then(function(metadata) { try { @@ -183,12 +185,12 @@ function OKAdminView(options) { resource.create(data).then(function(created) { req.flash('success', {action: 'create'}); res.redirect(303, resource.getID(data)); - }).fail(errorHandler(req, res)); + }).fail(error(req, res, 500)); } catch (errors) { - var templateData = getResourceTemplateData(metadata, resource, data); + var templateData = transformData(metadata, resource, data); view.renderResource(req, res, assign(templateData, {errors: errors})); } - }).fail(errorHandler(req, res));; + }).fail(error(req, res, 500));; } }); @@ -198,11 +200,9 @@ function OKAdminView(options) { var resourcesJSON = body[type]; var resource = resourceCache.get(type); if (!resourcesJSON || !resourcesJSON.length) { - res.status(400); - errorHandler(req, res)(new Error('Bad request')); + error(req, res, 400)(new Error('Bad request')); } else if (!resource) { - res.status(404); - errorHandler(req, res)(new Error('No such resource')); + error(req, res, 404)(new Error('No such resource')); } else { try { var ids = []; @@ -212,7 +212,7 @@ function OKAdminView(options) { return data; }); } catch (e) { - errorHandler(req, res)(new Error('Resource batch contains invalid JSON')); + error(req, res, 500)(new Error('Resource batch contains invalid JSON')); return; } Q.all([ @@ -222,7 +222,7 @@ function OKAdminView(options) { var metadata = results.shift(); req.flash('success', {action: 'batch_update'}); res.redirect(303, '../..'); - }).fail(errorHandler(req, res)); + }).fail(error(req, res, 500)); } }); @@ -232,7 +232,7 @@ function OKAdminView(options) { var data = req.body; var resource = resourceCache.get(type, id); if (!resource) { - errorHandler(req, res)(new Error('No such resource ' + type)); + error(req, res, 400)(new Error('No such resource ' + type)); } else { // TODO Prob should make metadata synchronous... meta.get().then(function(metadata) { @@ -241,12 +241,12 @@ function OKAdminView(options) { resource.update(id, data).then(function(updated) { req.flash('success', {action: 'update'}); res.redirect(303, '../' + resource.getID(updated)); - }).fail(errorHandler(req, res)); + }).fail(error(req, res, 500)); } catch (errors) { - var templateData = getResourceTemplateData(metadata, resource, data); + var templateData = transformData(metadata, resource, data); view.renderResource(req, res, assign(templateData, {errors: errors})); } - }).fail(errorHandler(req, res)); + }).fail(error(req, res, 500)); } }); @@ -255,14 +255,14 @@ function OKAdminView(options) { var id = req.params.id; var resource = resourceCache.get(type, id); if (!resource) { - errorHandler(req, res)(new Error('No such resource ' + type)); + error(req, res, 500)(new Error('No such resource ' + type)); } else { meta.get().then(function(metadata) { resource.destroy(id).then(function() { req.flash('success', {action: 'delete'}); res.redirect(303, '../..'); - }).fail(errorHandler(req, res)); - }).fail(errorHandler(req, res)); + }).fail(error(req, res, 500)); + }).fail(error(req, res, 500)); } }); @@ -271,9 +271,9 @@ function OKAdminView(options) { } /** - * Get template data for a single resource + * Yields formatted template data for a single resource */ -function getResourceTemplateData(meta, resource, data) { +function transformData(meta, resource, data) { meta = meta || {}; resource = resource || {}; data = data || {}; @@ -306,21 +306,21 @@ OKAdminView.prototype.renderIndex = function(req, res, data) { data = data || {}; this._templates['index'].render(data).then(function(rendered) { res.send(rendered); - }).fail(errorHandler(req, res)); + }).fail(this._error(req, res, 500)); }; OKAdminView.prototype.renderResource = function(req, res, data) { data = data || {}; this._templates['resource'].render(data).then(function(rendered) { res.send(rendered); - }).fail(errorHandler(req, res)); + }).fail(this._error(req, res, 500)); }; OKAdminView.prototype.renderResourceNew = function(req, res, data) { data = data || {meta: {}, resource: {}}; this._templates['resource_new'].render(data).then(function(rendered) { res.send(rendered); - }).fail(errorHandler(req, res)); + }).fail(this._error(req, res, 500)); }; /** @@ -378,30 +378,15 @@ function fetchResourceTemplateData(meta, query, fn) { return Q.promise(function(resolve, reject) { meta.get().then(function(metadata) { query.get().then(function(data) { - var resource = query.resource; - resolve(fn(metadata, resource, data)); + if (!data) { + reject(new Error('No resource data')); + } else { + var resource = query.resource; + resolve(fn(metadata, resource, data)); + } }).fail(reject); }).fail(reject) }); } -/** - * TODO Real error handling - */ -function errorHandler(req, res) { - return function(err) { - res.send(err.stack); - }; -} - -/** - * TODO Real 404 handling - */ -function resourceMissingHandler(req, res) { - return function() { - res.status(404); - res.send('404'); - } -} - module.exports = OKAdminView; |
