alexa-ability
Advanced tools
Comparing version 0.10.1 to 0.11.0
@@ -24,29 +24,52 @@ # `Ability` | ||
### `use(...handlers) -> ability` | ||
Add middleware functions to your ability that will be called for every request. | ||
Middleware functions will be called in the order added. | ||
Add a handler function to your ability. Handlers will be executed sequentially, | ||
therefore the order handlers are added is important. | ||
Each handler function must accept two arguments: | ||
- `req`: the request Object | ||
- `next`: a function to call when the middleware is finished or has failed. If | ||
this function is called with an error as its first argument, the error handler | ||
will immediately be called. | ||
A handler function can accept either 2 or 3 arguments. | ||
If the function accepts 2 (or less) arguments it will handle requests. The | ||
arguments are: | ||
- `req`: the request object | ||
- `next`: a function to call when the middleware is finished or has failed. If | ||
this function is called with an error as its first argument, the error handler | ||
will immediately be called. | ||
If the function accepts 3 arguments it will handle errors. The arguments are: | ||
- `err`: the error being handled | ||
- `req`: the request object | ||
- `next`: a function to call when the handler is finished or has failed. You'll | ||
typically never need to use this. | ||
##### Example | ||
```js | ||
app.use(function(req, next) { | ||
// we can do things asynchronously! | ||
validateRequest(req, function(err, isValid) { | ||
// let error handler handle any errors | ||
if (err) return next(err); | ||
console.log('handle request 1'); | ||
next(); | ||
}); | ||
// you can send responses from here | ||
if (!isValid) { | ||
res.say('Invalid.').end(); | ||
return; // just make sure not to call "next" if you do | ||
} | ||
app.use(function(err, req, next) { | ||
// there are no errors upstream, this error handler will be skipped | ||
console.log('handle error 1'); | ||
next(); | ||
}); | ||
// move on | ||
next(); | ||
}); | ||
// uhoh, a wild error appeared | ||
app.use((req, next) => next(new Error())); | ||
app.use(function(req, next) { | ||
// there's an error upstream, this request handler will be skipped | ||
console.log('handle request 2'); | ||
next(); | ||
}); | ||
app.use(function(err, req, next) { | ||
// upstream error! this function is called | ||
console.log('handle error 2'); | ||
next(); | ||
}); | ||
// will output: | ||
// handle request 1 | ||
// handle error 2 | ||
``` | ||
@@ -60,17 +83,10 @@ | ||
Each handler function must accept two arguments: | ||
- `req`: the request Object | ||
- `next`: a function to call when the handler is finished or has failed. If this | ||
function is called with an error as its first argument, the error handler will | ||
immediately be called. | ||
See `ability.use()` for possible arguments. | ||
##### Example | ||
```js | ||
// handler | ||
function handleIntent(req, next) { | ||
app.on('MyIntent', function(req, next) { | ||
req.say('Hello World!').end(); | ||
} | ||
}); | ||
app.on('MyIntent', handleIntent); | ||
// is equivalent to | ||
@@ -87,15 +103,2 @@ app.use((req, next) => { | ||
### `onError(handler) -> ability` | ||
Add a general error handler to your ability. Calling this function multiple times | ||
will __replace__ the previously added error handler, not append it. Typically your | ||
error handler should be very simple, and gracefully tell the user that there was was | ||
a problem. | ||
Each error handling function must accept three arguments: | ||
- `err`: the error being handled | ||
- `req`: the request Object | ||
- `next`: a function to call when the handler is finished or has failed. You'll | ||
typically never need to use this. | ||
### `handle(data, callback) -> request` | ||
@@ -102,0 +105,0 @@ Handle a request from Amazon. This function accepts two arguments: |
@@ -28,4 +28,2 @@ 'use strict'; | ||
var _defaultHandlers = require('./defaultHandlers'); | ||
var _resolve = require('./resolve'); | ||
@@ -66,3 +64,2 @@ | ||
this._stack = []; | ||
this._onError = null; | ||
@@ -120,8 +117,2 @@ if (options.applicationId) { | ||
}, { | ||
key: 'onError', | ||
value: function onError(handler) { | ||
this._onError = handler; | ||
return this; | ||
} | ||
}, { | ||
key: 'handle', | ||
@@ -131,3 +122,2 @@ value: function handle(event) { | ||
var errHandler = this._onError || _defaultHandlers.defaultHandlers.errorHandler; | ||
var stack = [].concat(_toConsumableArray(this._stack)); | ||
@@ -170,12 +160,5 @@ var index = 0; | ||
// uhoh, try error handler once | ||
if (err) { | ||
hLog('executing error handler'); | ||
(0, _resolve.resolve)(errHandler, done, err, req, done); | ||
return; | ||
} | ||
// no more handlers? fail | ||
if (index >= stack.length) { | ||
done(); | ||
done(err); | ||
return; | ||
@@ -185,13 +168,16 @@ } | ||
var fn = stack[index++]; | ||
var fnName = fn.name || fn.displayName || 'anonymous'; | ||
// invalid handler? just skip it.. | ||
if (typeof fn !== 'function') { | ||
hLog('invalid handler %s', fn); | ||
next(); | ||
return; | ||
if (fn.length >= 3 && err) { | ||
hLog('executing error handler: <' + fnName + '>'); | ||
(0, _resolve.resolve)(fn, next, err, req); | ||
} else if (fn.length < 3 && !err) { | ||
// all's well! try the handler | ||
hLog('executing handler: <' + fnName + '>'); | ||
(0, _resolve.resolve)(fn, next, req); | ||
} else { | ||
// not correct type of handler | ||
hLog('skipping handler: <' + fnName + '>'); | ||
next(err); | ||
} | ||
// all's well! try the handler | ||
hLog('executing function <' + (fn.name || 'anonymous') + '>'); | ||
(0, _resolve.resolve)(fn, next, req); | ||
} | ||
@@ -198,0 +184,0 @@ |
@@ -15,6 +15,15 @@ "use strict"; | ||
function handleEvent(event, handler) { | ||
// return middleware function | ||
return function eventHandler(req, next) { | ||
return event === req.handler ? handler(req, next) : next(); | ||
var isMatch = function isMatch(req) { | ||
return req.handler === event; | ||
}; | ||
var isErrorHandler = handler.length >= 3; | ||
var fn = isErrorHandler ? function (err, req, next) { | ||
return isMatch(req) ? handler(err, req, next) : next(); | ||
} : function (req, next) { | ||
return isMatch(req) ? handler(req, next) : next(); | ||
}; | ||
fn.displayName = handler.name; // for debug statements | ||
return fn; | ||
} |
{ | ||
"name": "alexa-ability", | ||
"version": "0.10.1", | ||
"version": "0.11.0", | ||
"description": "An Alexa skills framework for node", | ||
@@ -5,0 +5,0 @@ "main": "lib/index.js", |
@@ -64,8 +64,2 @@ # alexa-ability [![Build Status](https://travis-ci.org/nickclaw/alexa-ability.svg?branch=master)](https://travis-ci.org/nickclaw/alexa-ability) | ||
// gracefully handle any uncaught errors | ||
ability.onError(function(err, req, next) { | ||
req.say('Uhoh, something went wrong').end(); | ||
}); | ||
// handle custom intents | ||
@@ -80,4 +74,16 @@ ability.on('MeaningOfLifeIntent', function(req, next) { | ||
// catches any unhandled requests | ||
ability.use(function(req, next) { | ||
req.say('I don\'t know what to say').end(); | ||
}); | ||
// gracefully handles any uncaught errors | ||
ability.use(function(err, req, next) { | ||
req.say('Uhoh, something went wrong').end(); | ||
}); | ||
// export as a lambda handler | ||
export const handler = handleAbility(ability); | ||
``` |
88
37329
20
491