Initial commit of stand-alone module

This commit is contained in:
James Allen 2018-03-07 16:42:39 +00:00
commit a94b34f37f
6 changed files with 349 additions and 0 deletions

2
libraries/o-error/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
node_modules/

View file

@ -0,0 +1,53 @@
'use strict'
var util = require('util')
/**
* Make custom error types. There are many, many modules for this, but they all
* seem a bit weird. This approach is based on
* https://gist.github.com/justmoon/15511f92e5216fa2624b
* which seems sensible. This module mainly tries to DRY it up a bit. It also
* incorporates some ideas from the verror package. Maybe it can become its own
* package one day.
*
* TODO: Will this work under browserify?
*
* @module
*/
function extendErrorType (base, name, builder) {
var errorConstructor = function () {
Error.captureStackTrace && Error.captureStackTrace(this, this.constructor)
if (builder) builder.apply(this, arguments)
this.name = name
}
util.inherits(errorConstructor, base)
errorConstructor.prototype.withCause = function (cause) {
this.cause = cause
if (this.message && cause.message) {
this.message += ': ' + cause.message
}
return this
}
return errorConstructor
}
function defineErrorType (name, builder) {
return extendErrorType(Error, name, builder)
}
function extendErrorTypeIn (container, base, name, builder) {
container[name] = extendErrorType(base, name, builder)
}
function defineErrorTypeIn (container, name, builder) {
extendErrorTypeIn(container, Error, name, builder)
}
exports.extend = extendErrorType
exports.define = defineErrorType
exports.extendIn = extendErrorTypeIn
exports.defineIn = defineErrorTypeIn

142
libraries/o-error/npm-shrinkwrap.json generated Normal file
View file

@ -0,0 +1,142 @@
{
"name": "overleaf-error-type",
"version": "1.0.0",
"dependencies": {
"chai": {
"version": "3.4.1",
"from": "chai@>=3.3.0 <4.0.0",
"resolved": "https://registry.npmjs.org/chai/-/chai-3.4.1.tgz",
"dependencies": {
"assertion-error": {
"version": "1.0.1",
"from": "assertion-error@>=1.0.1 <2.0.0",
"resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.0.1.tgz"
},
"deep-eql": {
"version": "0.1.3",
"from": "deep-eql@>=0.1.3 <0.2.0",
"resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz",
"dependencies": {
"type-detect": {
"version": "0.1.1",
"from": "type-detect@0.1.1",
"resolved": "https://registry.npmjs.org/type-detect/-/type-detect-0.1.1.tgz"
}
}
},
"type-detect": {
"version": "1.0.0",
"from": "type-detect@>=1.0.0 <2.0.0",
"resolved": "https://registry.npmjs.org/type-detect/-/type-detect-1.0.0.tgz"
}
}
},
"mocha": {
"version": "2.3.4",
"from": "mocha@>=2.3.3 <3.0.0",
"resolved": "https://registry.npmjs.org/mocha/-/mocha-2.3.4.tgz",
"dependencies": {
"commander": {
"version": "2.3.0",
"from": "commander@2.3.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.3.0.tgz"
},
"debug": {
"version": "2.2.0",
"from": "debug@2.2.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
"dependencies": {
"ms": {
"version": "0.7.1",
"from": "ms@0.7.1",
"resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz"
}
}
},
"diff": {
"version": "1.4.0",
"from": "diff@1.4.0",
"resolved": "https://registry.npmjs.org/diff/-/diff-1.4.0.tgz"
},
"escape-string-regexp": {
"version": "1.0.2",
"from": "escape-string-regexp@1.0.2",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz"
},
"glob": {
"version": "3.2.3",
"from": "glob@3.2.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-3.2.3.tgz",
"dependencies": {
"graceful-fs": {
"version": "2.0.3",
"from": "graceful-fs@>=2.0.0 <2.1.0",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-2.0.3.tgz"
},
"inherits": {
"version": "2.0.1",
"from": "inherits@>=2.0.0 <3.0.0",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
},
"minimatch": {
"version": "0.2.14",
"from": "minimatch@>=0.2.11 <0.3.0",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz",
"dependencies": {
"lru-cache": {
"version": "2.7.3",
"from": "lru-cache@>=2.0.0 <3.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz"
},
"sigmund": {
"version": "1.0.1",
"from": "sigmund@>=1.0.0 <1.1.0",
"resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz"
}
}
}
}
},
"growl": {
"version": "1.8.1",
"from": "growl@1.8.1",
"resolved": "https://registry.npmjs.org/growl/-/growl-1.8.1.tgz"
},
"jade": {
"version": "0.26.3",
"from": "jade@0.26.3",
"resolved": "https://registry.npmjs.org/jade/-/jade-0.26.3.tgz",
"dependencies": {
"commander": {
"version": "0.6.1",
"from": "commander@0.6.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-0.6.1.tgz"
},
"mkdirp": {
"version": "0.3.0",
"from": "mkdirp@0.3.0",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz"
}
}
},
"mkdirp": {
"version": "0.5.0",
"from": "mkdirp@0.5.0",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz",
"dependencies": {
"minimist": {
"version": "0.0.8",
"from": "minimist@0.0.8",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz"
}
}
},
"supports-color": {
"version": "1.2.0",
"from": "supports-color@1.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-1.2.0.tgz"
}
}
}
}
}

View file

@ -0,0 +1,16 @@
{
"name": "overleaf-error-type",
"version": "1.0.0",
"description": "Utility for creating custom error types.",
"main": "index.js",
"scripts": {
"test": "mocha --require test/support"
},
"author": "team@overleaf.com",
"license": "Proprietary",
"private": true,
"devDependencies": {
"chai": "^3.3.0",
"mocha": "^2.3.3"
}
}

View file

@ -0,0 +1,131 @@
'use strict'
var errorType = require('..')
describe('errorType', function () {
it('defines a custom error type', function () {
var CustomError = errorType.define('CustomError')
function doSomethingBad () {
throw new CustomError()
}
try {
doSomethingBad()
expect.fail('should have thrown')
} catch (e) {
// should set the name to the error's name
expect(e.name).to.equal('CustomError')
// should be an instance of the error type
expect(e instanceof CustomError).to.be.true
// should be an instance of the built-in Error type
expect(e instanceof Error).to.be.true
// should be recognised by util.isError
expect(require('util').isError(e)).to.be.true
// should have a stack trace
expect(e.stack).to.be.truthy
// toString should return the default error message formatting
expect(e.toString()).to.equal('CustomError')
// stack should start with the default error message formatting
expect(e.stack.split('\n')[0], 'CustomError')
// first stack frame should be the function where the error was thrown
expect(e.stack.split('\n')[1]).to.match(/doSomethingBad/)
}
})
it('defines a custom error type with a message', function () {
var CustomError = errorType.define('CustomError', function (x) {
this.message = 'x=' + x
this.x = x
})
function doSomethingBad () {
throw new CustomError('foo')
}
try {
doSomethingBad()
expect.fail('should have thrown')
} catch (e) {
expect(e.toString()).to.equal('CustomError: x=foo')
expect(e.message).to.equal('x=foo')
expect(e.x).to.equal('foo')
}
})
it('defines extended error type', function () {
var BaseError = errorType.define('BaseError')
var DerivedError = errorType.extend(BaseError, 'DerivedError')
function doSomethingBad () {
throw new DerivedError()
}
try {
doSomethingBad()
expect.fail('should have thrown')
} catch (e) {
expect(e.toString()).to.equal('DerivedError')
}
})
it('defines error types in a container object', function () {
var SomeClass = {}
errorType.defineIn(SomeClass, 'CustomError')
function doSomethingBad () {
throw new SomeClass.CustomError()
}
try {
doSomethingBad()
expect.fail('should have thrown')
} catch (e) {
expect(e.toString()).to.equal('CustomError')
}
})
it('extends error types in a container object', function () {
var SomeClass = {}
errorType.defineIn(SomeClass, 'CustomError', function (payload) {
this.message = 'custom error'
this.payload = payload
})
errorType.extendIn(SomeClass, SomeClass.CustomError, 'DerivedCustomError',
function (payload) {
SomeClass.CustomError.call(this, payload)
this.message = 'derived custom error'
})
function doSomethingBad () {
throw new SomeClass.CustomError(123)
}
try {
doSomethingBad()
expect.fail('should have thrown')
} catch (e) {
expect(e.toString()).to.equal('CustomError: custom error')
expect(e.payload).to.equal(123)
}
function doSomethingBadWithDerived () {
throw new SomeClass.DerivedCustomError(456)
}
try {
doSomethingBadWithDerived()
expect.fail('should have thrown')
} catch (e) {
expect(e.toString()).to.equal('DerivedCustomError: derived custom error')
expect(e.payload).to.equal(456)
}
})
})

View file

@ -0,0 +1,5 @@
'use strict'
var chai = require('chai')
global.expect = chai.expect