Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Simple error creation and passing utilities focused on:
You should know by now that a String is not an Error. Unfortunately the Error
constructor in Javascript isn't all that convenient either. How often do you find yourself in this situation?
var err = new Error('This is an error. There are many like it.');
err.someProperty = 'more syntax';
err.someOtherProperty = 'it wont stop.';
err.notEven = 'for the mayor';
throw err;
Rest your fingers, errs
is here to help. The following is equivalent to the above:
var errs = require('errs');
throw errs.create({
message: 'This is an error. There are many like it.',
someProperty: 'more syntax',
someOtherProperty: 'it wont stop.',
notEven: 'for the mayor'
});
## Reusing Custom Error Types
errs
also exposes an inversion of control interface for easily reusing custom error types across your application. Custom Error Types registered with errs
will transparently invoke Error
constructor and Error.captureStackTrace
to attach transparent stack traces:
/*
* file-a.js: Create and register your error type.
*
*/
var util = require('util'),
errs = require('errs');
function MyError() {
this.message = 'This is my error; I made it myself. It has a transparent stack trace.';
}
//
// Alternatively `MyError.prototype.__proto__ = Error;`
//
util.inherits(MyError, Error);
//
// Register the error type
//
errs.register('myerror', MyError);
/*
* file-b.js: Use your error type.
*
*/
var errs = require('errs');
console.log(
errs.create('myerror')
.stack
.split('\n')
);
The output from the two files above is shown below. Notice how it contains no references to errs.js
:
[ 'MyError: This is my error; I made it myself. It has a transparent stack trace.',
' at Object.<anonymous> (/file-b.js:19:8)',
' at Module._compile (module.js:441:26)',
' at Object..js (module.js:459:10)',
' at Module.load (module.js:348:31)',
' at Function._load (module.js:308:12)',
' at Array.0 (module.js:479:10)',
' at EventEmitter._tickCallback (node.js:192:40)' ]
## Merging with Existing Errors
When working with errors you catch or are returned in a callback you can extend those errors with properties by using the errs.merge
method. This will also create a human readable error message and stack-trace:
process.on('uncaughtException', function(err) {
console.log(errs.merge(err, {namespace: 'uncaughtException'}));
});
var file = fs.createReadStream('FileDoesNotExist.here');
{ [Error: Unspecified error]
name: 'Error',
namespace: 'uncaughtException',
errno: 34,
code: 'ENOENT',
path: 'FileDoesNotExist.here',
description: 'ENOENT, no such file or directory \'FileDoesNotExist.here\'',
stacktrace: [ 'Error: ENOENT, no such file or directory \'FileDoesNotExist.here\'' ] }
## Optional Callback Invocation
Node.js handles asynchronous IO through the elegant EventEmitter
API. In many scenarios the callback
may be optional because you are returning an EventEmitter
for piping or other event multiplexing. This complicates code with a lot of boilerplate:
function importantFeature(callback) {
return someAsyncFn(function (err) {
if (err) {
if (callback) {
return callback(err);
}
throw err;
}
});
}
errs
it presents a common API for both emitting error
events and invoking continuations (i.e. callbacks) with errors. If a callback
is supplied to errs.handle()
it will be invoked with the error. It no callback
is provided then an EventEmitter
is returned which emits an error
event on the next tick:
function importantFeature(callback) {
return someAsyncFn(function (err) {
if (err) {
return errs.handle(err, callback);
}
});
}
## Piping Errors
Often when working with streams (especially when buffering for whatever reason), you may have already returned an EventEmitter
or Stream
instance by the time an error is handled.
function pipeSomething(callback) {
//
// You have a stream (e.g. http.ResponseStream) and you
// have an optional `callback`.
//
var stream = new require('stream').Stream;
//
// You need to do something async which may respond with an
// error
//
getAnotherStream(function (err, source) {
if (err) {
if (callback)
callback(err);
}
stream.emit('error', err);
return;
}
source.pipe(stream);
})
return stream;
}
You may pass either a function
or EventEmitter
instance to errs.handle
.
function pipeSomething(callback) {
//
// You have a stream (e.g. http.ResponseStream) and you
// have an optional `callback`.
//
var stream = new require('stream').Stream;
//
// You need to do something async which may respond with an
// error
//
getAnotherStream(function (err, source) {
if (err) {
//
// Invoke the callback if it exists otherwise the stream.
//
return errs.handle(err, callback || stream);
}
source.pipe(stream);
})
return stream;
}
If you wish to invoke both a callback
function and an error
event simply pass both:
errs.handle(err, callback, stream);
The errs
modules exposes some simple utility methods:
.create(type, opts)
: Creates a new error instance for with the specified type
and opts
. If the type
is not registered then a new Error
instance will be created..register(type, proto)
: Registers the specified proto
to type
for future calls to errors.create(type, opts)
..unregister(type)
: Unregisters the specified type
for future calls to errors.create(type, opts)
..handle(err, callback)
: Attempts to instantiate the given error
. If the error
is already a properly formed error
object (with a stack
property) it will not be modified..merge(err, type, opts)
: Merges an existing error with a new error instance for with the specified type
and opts
. $ curl http://npmjs.org/install.sh | sh
$ [sudo] npm install errs
All tests are written with vows and should be run with npm:
$ npm test
FAQs
Simple error creation and passing utilities
The npm package errs receives a total of 20,252 weekly downloads. As such, errs popularity was classified as popular.
We found that errs demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.