node-barefoot
Advanced tools
Comparing version 0.0.5 to 0.0.6
# Changes | ||
## 0.0.6 | ||
* `APIAdapter.Server` uses [winston](https://github.com/flatiron/winston) for logging errors now | ||
* `APIAdapter.Server` does not crash anymore if an `error` callback does not supply an error object as argument | ||
* `APIAdapter.Server` forwards the error message to the REST HTTP client for easier bug tracking | ||
## 0.0.5 | ||
* Stack multiple callbacks to an APIAdapter route. Call `success` to proceed with the next callback, call `error` to stop the execution of any further callback. | ||
* Stack multiple callbacks to an APIAdapter route. Call `success` to proceed with the next callback, call `error` to stop the execution of any further callback. |
@@ -28,2 +28,3 @@ /** Mixin: Barefoot.APIAdapter.Server | ||
var _ = require('underscore') | ||
, winston = require('winston') | ||
, httpMethods = require('methods') | ||
@@ -38,2 +39,10 @@ , methodMap = { | ||
/** Function: toString | ||
* String representation of this module. | ||
*/ | ||
function toString() { | ||
return 'APIAdapter.Server'; | ||
} | ||
/** PrivateFunction: processCallbacks | ||
@@ -112,2 +121,8 @@ * This function is used to run a callback function or an array of stacked | ||
} catch(err) { | ||
winston.log('error', 'API callback caused exceptional error', { | ||
source: toString() | ||
, apiRoute: req.originalUrl | ||
, err: err.toString() || err | ||
, stack: err.stack || undefined | ||
}); | ||
errorHandler.call(handlerScope, err); | ||
@@ -191,17 +206,32 @@ } | ||
function createExpressJsRoute(url, callbacks, expressJsMethod, app) { | ||
var expressJsHandler = createExpressJsCallback( | ||
function success(apiResult, httpStatusCode) { | ||
httpStatusCode = httpStatusCode || 200; | ||
this.res.send(httpStatusCode, apiResult); | ||
} | ||
, function error(err) { | ||
if(_.has(err, 'httpStatusCode')) { | ||
this.res.send(err.httpStatusCode); | ||
} else { | ||
this.res.send(500); | ||
var self = this | ||
, expressJsHandler = createExpressJsCallback( | ||
function success(apiResult, httpStatusCode) { | ||
httpStatusCode = httpStatusCode || 200; | ||
this.res.send(httpStatusCode, apiResult); | ||
} | ||
} | ||
, callbacks | ||
, app); | ||
, function error(err) { | ||
var message | ||
, stack | ||
, httpStatusCode = 500; | ||
if(!_.isUndefined(err)) { | ||
if(_.has(err, 'httpStatusCode')) { | ||
httpStatusCode = err.httpStatusCode; | ||
} | ||
message = err.toString() || err; | ||
stack = err.stack || undefined; | ||
} | ||
this.res.send(httpStatusCode, message); | ||
winston.log('error', 'API callback stopped with error', { | ||
source: self.toString() | ||
, apiRoute: url | ||
, err: message | ||
, stack: stack | ||
}); | ||
} | ||
, callbacks | ||
, app); | ||
expressJsMethod.call(app, url, expressJsHandler); | ||
@@ -252,2 +282,32 @@ } | ||
/** PrivateFunction: extractParams | ||
* Takes a match object of a regex execution and extracts the parameters | ||
* identified by keys. All values are returned inside an array at the end. | ||
* | ||
* Thanks to: | ||
* * https://github.com/visionmedia/express/blob/master/lib/router/route.js#L50 | ||
* Paremters: | ||
* (Object) match - Resulting match object of an executed Regexp | ||
* (Object) keys - Keys to extract | ||
* (Object) params - An object which will contain all extracted parameters | ||
* from url, if a route matched. | ||
*/ | ||
function extractParams(match, keys, params) { | ||
params = params || {}; | ||
for(var i = 1, l = match.length; i < l; ++i) { | ||
var key = keys[i - 1]; | ||
var val = 'string' === typeof match[i] ? | ||
decodeURIComponent(match[i]) : | ||
match[i]; | ||
if(key) { | ||
params[key.name] = val; | ||
} else { | ||
params.push(val); | ||
} | ||
} | ||
} | ||
/** PrivateFunction: matchRoute | ||
@@ -279,29 +339,14 @@ * This function takes an HTTP method and a URL. It tries to match any API route | ||
, matchedRoute; | ||
params = params || []; | ||
_.every(routes, function(route) { | ||
var keys = route.keys | ||
, m = route.regexp.exec(url); | ||
for(var routeUrl in routes) { | ||
var route = routes[routeUrl] | ||
, keys = route.keys | ||
, match = route.regexp.exec(url); | ||
if(m) { | ||
if(match) { | ||
matchedRoute = route; | ||
for(var i = 1, l = m.length; i < l; ++i) { | ||
var key = keys[i - 1]; | ||
var val = 'string' === typeof m[i] ? | ||
decodeURIComponent(m[i]) : | ||
m[i]; | ||
if(key) { | ||
params[key.name] = val; | ||
} else { | ||
params.push(val); | ||
} | ||
} | ||
return true; | ||
} else { | ||
return false; | ||
extractParams(match, keys, params); | ||
break; | ||
} | ||
}); | ||
} | ||
@@ -397,3 +442,4 @@ return matchedRoute; | ||
function dispatchLocalApiCall(httpMethod, url, data, options) { | ||
var params = {} | ||
var self = this | ||
, params = {} | ||
, matchedRoute = matchRoute(httpMethod, url, this.apiRoutes, params); | ||
@@ -407,6 +453,35 @@ options = options || {}; | ||
var successHandler = function successHandler(apiResult) { | ||
if(_.has(options, 'success')) { options.success(apiResult); } | ||
if(_.has(options, 'success')) { | ||
options.success(apiResult); | ||
} else { | ||
winston.log('info', 'No success callback defined', { | ||
source: self.toString() | ||
, apiRoute: url | ||
}); | ||
} | ||
} | ||
, errorHandler = function errorHandler(err) { | ||
if(_.has(options, 'error')) { options.error(err); } | ||
var message | ||
, stack; | ||
if(!_.isUndefined(err)) { | ||
message = err.toString() || err; | ||
stack = err.stack || undefined; | ||
} | ||
if(_.has(options, 'error')) { | ||
options.error(err); | ||
} else { | ||
winston.log('info', 'No error callback defined', { | ||
source: toString() | ||
, apiRoute: url | ||
}); | ||
} | ||
winston.log('error', 'API callback stopped with error', { | ||
source: self.toString() | ||
, apiRoute: url | ||
, err: message | ||
, stack: stack | ||
}); | ||
}; | ||
@@ -465,2 +540,3 @@ | ||
, sync: sync | ||
, toString: toString | ||
}; |
{ | ||
"name": "node-barefoot" | ||
, "version": "0.0.5" | ||
, "version": "0.0.6" | ||
, "description": "Barefoot makes code sharing between browser and server reality. Write your application once and run it on both ends of the wire." | ||
@@ -22,2 +22,3 @@ , "keywords": [ | ||
, "methods": "~0.0.1" | ||
, "winston": "~0.7.1" | ||
} | ||
@@ -24,0 +25,0 @@ , "devDependencies": { |
Sorry, the diff of this file is not supported yet
717936
133
5386
7
+ Addedwinston@~0.7.1
+ Addedasync@0.2.10(transitive)
+ Addedaws-sign@0.2.1(transitive)
+ Addedboom@0.3.8(transitive)
+ Addedcolors@0.6.2(transitive)
+ Addedcombined-stream@0.0.7(transitive)
+ Addedcookie-jar@0.2.0(transitive)
+ Addedcryptiles@0.1.3(transitive)
+ Addedcycle@1.0.3(transitive)
+ Addeddelayed-stream@0.0.5(transitive)
+ Addedeyes@0.1.8(transitive)
+ Addedforever-agent@0.2.0(transitive)
+ Addedform-data@0.0.10(transitive)
+ Addedhawk@0.10.2(transitive)
+ Addedhoek@0.7.6(transitive)
+ Addedjson-stringify-safe@3.0.0(transitive)
+ Addedmime@1.2.11(transitive)
+ Addednode-uuid@1.4.8(transitive)
+ Addedoauth-sign@0.2.0(transitive)
+ Addedpkginfo@0.3.1(transitive)
+ Addedqs@0.5.6(transitive)
+ Addedrequest@2.16.6(transitive)
+ Addedsntp@0.1.4(transitive)
+ Addedstack-trace@0.0.10(transitive)
+ Addedtunnel-agent@0.2.0(transitive)
+ Addedwinston@0.7.3(transitive)