Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

eraro

Package Overview
Dependencies
Maintainers
1
Versions
16
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

eraro - npm Package Compare versions

Comparing version 0.1.3 to 0.1.4

201

eraro.js
/* Copyright (c) 2014 Richard Rodger, MIT License */
"use strict";
/* jshint node:true, asi:true, eqnull:true */
var util = require('util')
// Create JavaScript Error objects with code strings, context details, and templated messages.
"use strict";
// Remove unwanted lines containing markers
function cleanstack( error, markers ) {
var stack = error ? error.stack : null
var out = ''
if( stack ) {
var lines = stack.split('\n')
var done = false
// #### System modules
var util = require('util')
line_loop:
for( var i = 1; i < lines.length; i++ ) {
var line = lines[i]
var found = false
for( var j = 0; j < markers.length; j++ ) {
found = ( -1 != line.indexOf( markers[j] ) )
if( found ) break;
}
if( !found ) break line_loop;;
}
// #### External modules
var _ = require('underscore')
out = ([lines[0]].concat(lines.slice(i))).join('\n')
}
return out
}
// #### Exports
module.exports = eraro
// make an error function
module.exports = function( options ) {
// #### Create an _eraro_ function
// Parameters:
//
// * _options_ : (optional) Object; properties:
// * _package_ : (optional) String; package name to mark Error objects
// * _module_ : (optional) Object; _module_ object to use as starting point for _require_ calls
// * _msgmap_ : (optional) Object; map codes to message templates
//
// Returns: Function
//
// The created function has parameters:
//
// * _exception_ : (optional) Error; the original exception to be wrapped
// * _code_ : (optional) String; code value
// * _message_ : (optional) String; error message, will be processed as a template
// * _details_ : (optional) Object; contextual details of the error, used to insert details into message
//
// and returns an Error object (to be thrown or used in a callback, as needed).
// The returned Error object has the following additional properties:
//
// * _code_: String; the code string
// * _package_: String; the package name
// * _**package-name**_: Boolean (true); a convenience marker for the package
// * _msg_: String; the generated message, may differ from original exception message (if any)
// * _details_: Object; contextual details of error
// * _callpoint_: String; first line of stacktrace that is external to eraro and calling module
function eraro( options ) {
options = options || {}
var msgprefix = options.package ? options.package+': ' : ''
var packaje = options.package || 'unknown'
var markers = options.markers || []
var msgprefix = options.package ? options.package+': ' : ''
var packaje = options.package || 'unknown'
var callmodule = options.module || module
var msgmap = options.msgmap || {}
var filename = module.filename
if( filename ) markers.push(filename)
var markers = [module.filename]
var parentfilename = module.parent ? module.parent.filename : null
if( parentfilename ) markers.push(parentfilename)
var filename = callmodule.filename
if( filename ) markers.push(filename);

@@ -65,11 +77,6 @@

code = 'string' === typeof(code) ? code : 'unknown'
code = _.isString(code) ? code : 'unknown'
details = _.isObject(details) ? details : (_.isObject(msg) && !_.isString(msg) ? msg : {})
msg = buildmessage(msg,msgmap,msgprefix,code,details)
details =
('object' === typeof(details)) ?
details :
('object' === typeof(msg) && 'string' !== typeof(msg) ? msg : {});
msg = msgprefix + ('string' === typeof(msg) ? msg : code)
if( !ex ) {

@@ -79,16 +86,114 @@ ex = new Error(msg)

ex[packaje] = true
ex.package = packaje
ex.code = code
ex[packaje] = true
ex.package = packaje
ex.msg = msg
ex.details = details
ex.callpoint = callpoint( ex, markers )
ex.code = code
ex.details = details || {}
return ex;
}
}
// clean the stack
if( internalex ) {
ex.stack = cleanstack( ex, markers )
// #### Find the first external stack trace line.
// Parameters:
//
// * _error_ : (optional) Error; provides the stack
// * _markers_ : (optional) Array[String]; ignore lines containing these strings
//
// Returns: String; stack trace line, with indent removed
function callpoint( error, markers ) {
markers = _.isArray(markers) ? markers : []
var stack = error ? error.stack : null
var out = ''
if( stack ) {
var lines = stack.split('\n')
var done = false
var i
line_loop:
for( i = 1; i < lines.length; i++ ) {
var line = lines[i]
var found = false
for( var j = 0; j < markers.length; j++ ) {
if( _.isString( markers[j] ) ) {
found = ( -1 != line.indexOf( markers[j] ) )
if( found ) break;
}
}
if( !found ) break line_loop;
}
return ex;
out = lines[i].substring(4)
}
return out
}
// #### Build the message string from a template by inserting details
// Uses the underscore template function with default settings.
// The original message (_msg_) has priority over messages from the _msgmap_.
// If no message can be found, the _code_ is used as a message.
// If an insert property is not defined, it is replaced with _[name?]_ in the message.
// As a convenience, _util_ and ___ are made available in the templates.
//
// Parameters:
//
// * _msg_ : (required) String; message template
// * _msgmap_ : (required) Object; map codes to message templates
// * _msgprefix_: (required) String; prefix for all messages, useful as indentification of error origin
// * _code_: (required) String; error code
// * _details_: (required) Object; error details providing context
//
// Returns: String; human readable error message
function buildmessage(msg,msgmap,msgprefix,code,details) {
var message = msgprefix + (_.isString(msg) ? msg : _.isString(msgmap[code]) ? msgmap[code] : code )
// These are the inserts.
var valmap = _.extend({},details,{code:code})
// Workaround to prevent underscore blowing up if properties are not found.
// Reserved words and undefined need to be suffixed with $ in the template interpolates.
var valstrmap = {util:util,_:_}
_.each(valmap,function(val,key){
/* jshint evil:true */
try { eval('var '+key+';') } catch(e) { key = key+'$' }
if( {'undefined':1,'NaN':1}[key] ) { key = key+'$' }
valstrmap[key] = val
})
var done = false
while( !done ) {
try {
message = _.template( message, valstrmap )
done = true
}
catch(e) {
if(e instanceof ReferenceError) {
var m = /ReferenceError:\s+(.*?)\s+/.exec(e.toString())
if( m && m[1] ) {
valstrmap[m[1]]="["+m[1]+"?]"
}
else done = true
}
// Some other error - give up and just dump the properties at the end of the template.
else {
done = true
message = message+' VALUES:'+util.inspect(valmap,{depth:2})+' TEMPLATE ERROR: '+e
}
}
}
return message
}
{
"name": "eraro",
"version": "0.1.3",
"description": "Create JavaScript Error objects with code strings, context details, and uncluttered stacktraces",
"version": "0.1.4",
"description": "Create JavaScript Error objects with code strings, context details, and templated messages.",
"main": "eraro.js",
"scripts": {
"test": "node test/eraro.test.js"
"test": "node test/eraro.test.js",
"jshint": "./node_modules/.bin/jshint eraro.js",
"docco": "./node_modules/.bin/docco eraro.js -o doc",
"gh-pages-doc": "cp -r doc/* ../gh-pages/eraro/doc"
},

@@ -22,3 +25,16 @@ "repository": {

},
"homepage": "https://github.com/rjrodger/eraro"
"homepage": "https://github.com/rjrodger/eraro",
"dependencies": {
"underscore": "~1.6.0"
},
"devDependencies": {
"mocha": "~1.18.2",
"docco": "~0.6.3",
"jshint": "~2.5.0"
},
"files": [
"README.md",
"LICENSE.txt",
"eraro.js"
]
}
eraro
=====
### Create JavaScript Error objects with code strings, context details, and uncluttered stacktraces
#### Create JavaScript Error objects with code strings, context details, and templated messages.
For use in library modules to generate contextual errors. Your library
module can return an error code for programmatic inspection by calling
code, and error details as a context object for custom messages and
fault inspection.
There is [annotated source code](http://rjrodger.github.io/eraro/doc/eraro.html) for this module.
Stack trace lines referring to _eraro_ itself, and your library, are
removed. This means that the first line of the stack trace refers to
the position in user code where your library was called.
For use in library modules to generate contextual errors with useful
meta data. Your library module can throw or pass (to a callback) an
_Error_ object that has additional properties, such as a _code_, that
can be used for programmatic inspection by client code that uses your
library.
# Quick example
```JavaScript
var error = require('eraro')()
var error = require('eraro')({package:'mylib'})
// throw an Error object that has a code
throw error('code_string')

@@ -29,23 +30,125 @@

throw error('code_string', {foo:1, bar:2})
// extend an existing Error object
var ex = new Error('Another message.')
throw error(ex,'code_string',{zed:3})
```
In all these cases, the Error object will have a _code_ property with value _"code_string"_.
// extend and existing Error object
var ex = new Error('Another message.')
throw error(ex,'code_string',{details:'data'})
# Usage
Use this module when you are writing a library that will be used by
application code. It allows your library to generate informative error messages.
The module itself is a generator function (taking options) that
returns the error-creating function that you will actually use. Thus
the most common way to use _eraro_ is to require and call immediately:
```JavaScript
var error = require('eraro')({package:'mylib'})
```
The Error object has the following additional properties:
The _error_ function can then be used in your library code. The
_error_ function generates _Error_ objects, which can be thrown or used in callbacks:
* _code_: code string
* _details_: context details object
```JavaScript
throw error('code1')
function doStuff( input, callback ) {
if( bad( input ) ) return callback( error('code2') );
}
```
The _package_ option is normally the name of your library. That is, the value
the _name_ property in _package.json_. The generated Error object will
have two properties to define the package: _package_, a string that is
the name of the package, and also a boolean, the name of the package itself.
This lets you check for the type of error easily:
```JavaScript
var error = require('eraro')({package:'mylib'})
### Support
var err0 = error('code0')
"mylib" === err0.package // true
err0.mylib // true
```
## Error details
You can supply additional contextual details for debugging or other
purposes. These are placed inside the _details_ property of the
generated Error:
```JavaScript
var error = require('eraro')({package:'mylib'})
var err0 = error('code0',{foo:'FOO',bar:'BAR'})
"FOO" === err0.details.foo
"BAR" === err0.details.bar
```
## Error codes and message templates
To provide consistent error messages to your users, you can define a set of message templates, keyed by code:
```JavaScript
var error = require('eraro')({package:'mylib',msgmap:{
code0: "The first error, foo is <%=foo%>.",
code1: "The second error, bar is <%=bar%>.",
}})
```
When you specify a code, and details, these are inserted into the message (if any) associated with that code:
```JavaScript
var err0 = error('code0',{foo:'FOO',bar:'BAR'})
"mylib: The first error, foo is FOO." === err0.message
```
The message templates are [underscorejs templates](http://underscorejs.org/#template)
with the default settings.
If you specify a message directly, this is also interpreted as a template:
```JavaScript
var err0 = error('code2',
'My custom message, details: <%=util.inspect(zed)%>',
{zed:{a:1,b:2}})
"mylib: My custom message, details: { a: 1, b: 2 }" === err0.message
```
# The returned Error object
The returned Error object has the following additional properties:
* _code_: String; the code string
* _package_: String; the package name
* _**package-name**_: Boolean (true); a convenience marker for the package
* _msg_: String; the generated message, may differ from original exception message (if any)
* _details_: Object; contextual details of error
* _callpoint_: String; first line of stacktrace that is external to eraro and calling module
You can pass in an existing Error object. The additional properties
will be added to it, but the original message will be used as the
message template, overriding any matching code message.
# In the Wild
For real-world usage examples, see:
* _[use-plugin](http://github.com/rjrodger/use-plugin)_: a utility for providing a plugin interface for extensions to your module
# Support
If you're using this module, feel free to contact me on twitter if you have any questions! :) [@rjrodger](http://twitter.com/rjrodger)
Current Version: 0.1.3
Current Version: 0.1.4

@@ -56,4 +159,2 @@ Tested on: node 0.10.26

...more docs to follow...
[Annotated Source](http://rjrodger.github.io/eraro/doc/eraro.html)
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc