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

node-code-error

Package Overview
Dependencies
Maintainers
1
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

node-code-error - npm Package Compare versions

Comparing version 0.1.42 to 1.0.0

50

error.js
'use strict'
var util = require('./util')
var __ = require('./i18n').__
var hasProp = {}.hasOwnProperty
var statusCodeMap = require('./httpStatusCode.json')
module.exports = CodeError
util.extend(CodeError, Error)
function CodeError (msg, code, originalError) {
CodeError.__super__.constructor.apply(this, arguments)
this._customCode = code
this.message = msg
this.originalError = originalError
extend(CodeError, Error)
function CodeError (opts, msg) {
CodeError.__super__.constructor.call(this)
this.message = statusCodeMap[opts.type] || opts.type + ' error' + (msg ? ': ' + msg : '')
this.status = opts.status || 500
this.code = buildCode(opts)
this.type = opts.type
return this
}
CodeError.prototype.toString = function () {
return this.name + ': ' + this.message
return this.message
}

@@ -23,6 +26,12 @@

message: this.message,
type: this.name
type: this.type
}
}
CodeError.prototype.attach = function (err) {
this.originalError = err
this.stack = err.stack
return this
}
CodeError.prototype.toLocaleJSON = function (opts, data) {

@@ -34,3 +43,3 @@ opts = opts || {}

localed.code = this.code
localed.type = this.name
localed.type = this.type
localed.status = this.status

@@ -40,6 +49,19 @@ return localed

Object.defineProperty(CodeError.prototype, 'code', {
get: function () {
return +('' + this._baseCode + this._customCode)
function buildCode (opts) {
opts.actionCode = opts.actionCode || ''
opts.objectCode = opts.objectCode || ''
return +('' + opts.typeCode + opts.objectCode + opts.actionCode)
}
function extend (child, parent) {
for (var key in parent) {
if (hasProp.call(parent, key)) child[key] = parent[key]
}
})
function Ctor () {
this.constructor = child
}
Ctor.prototype = parent.prototype
child.prototype = new Ctor()
child.__super__ = parent.prototype
return child
}
'use strict'
var CodeError = require('./error')
var util = require('./util')
var i18n = require('./i18n')
var Errors = {
_eMap: {},
_name2codeMaps: [],
_split: ' '
var CONFIG = {
splitLetter: ' ',
get: function (type, key) {
var map = this[type + 'Map']
return map && map[key]
}
}
Errors.get = function (name) {
if (!name || !util.isString(name) && !util.isNumber(name)) return null
name = ('' + name).toLowerCase()
return this._eMap[name]
}
Errors.extend = function (name, status, baseCode, customCode, message) {
if (!name || !util.isNumberLike(baseCode)) {
return null
}
var existed = this.get(name)
if (existed) return existed
util.extend(Ctor, CodeError)
function Ctor (msg, code, orignalError) {
if (Errors._useMsgCode && !util.isNumberLike(code)) {
orignalError = code
code = Errors.ensureCode(msg)
module.exports = function (type, msg) {
var codeObj
if (isNumber(type)) {
codeObj = {
type: type,
status: type,
typeCode: type
}
Ctor.__super__.constructor(msg, code, orignalError)
this.name = util.toErrorName(name)
this._baseCode = baseCode
this.status = this.statusCode = status || 500
if (customCode !== undefined) this._customCode = customCode
if (message !== undefined) this.message = message
} else {
codeObj = CONFIG.get('type', type)
if (!codeObj) throw new Error('unrecognized error type: ' + type)
}
this._eMap[name] = Ctor
return Ctor
if (msg) {
var arr = msg.split(CONFIG.splitLetter)
var objCode = CONFIG.get('object', arr[0])
var actCode = CONFIG.get('action', arr[1])
if (!isCode(objCode)) throw new Error('unrecognized error object')
if (!isCode(actCode)) throw new Error('unrecognized error action')
codeObj.objectCode = objCode
codeObj.actionCode = actCode
}
codeObj.type = type
return new CodeError(codeObj, msg)
}
Errors.configure = function (opts) {
module.exports.configure = function (opts) {
opts = opts || {}
if (opts.maps) this._name2codeMaps = opts.maps
if (opts.splitLetter) this._split = opts.splitLetter
// 对象映射
CONFIG.objectMap = opts.objectMap || {}
// 行为映射
CONFIG.actionMap = opts.actionMap || {}
// 错误类型映射
CONFIG.typeMap = opts.typeMap || {}
if (opts.splitLetter) CONFIG.splitLetter = opts.splitLetter
if (opts.i18n || opts.additionKeys) {

@@ -51,62 +53,25 @@ i18n.configure({

}
this._useMsgCode = !!opts.useMsgForCode
}
Errors.str2code = function (str) {
var arr = str.split(this._split)
var maps = this._name2codeMaps
var code = ''
arr.forEach(function (item, ind) {
var codePart = maps[ind] && maps[ind][item]
if (codePart !== undefined) code += codePart
})
if (!code) return 0
return +code
module.exports.extend = function (name, status, typeCode, objectCode, actionCode) {
var codeObj = {
type: name,
status: status,
typeCode: typeCode
}
if (objectCode !== undefined) codeObj.objectCode = objectCode
if (objectCode !== undefined) codeObj.actionCode = actionCode
CONFIG.typeMap[name] = codeObj
}
Errors.ensureCode = function (code) {
if (util.isNumberLike(code)) return +code
if (util.isString(code) && ~code.indexOf(this._split)) {
return this.str2code(code)
}
return null
function isNumber (str) {
return typeof str == 'number'
}
Errors.wrap = function (err, type) {
if (!type) {
type = err.status || err.statusCode || 500
}
var Err = this.get(type)
if (!Err) return null
var msg = err.message || '' + err
var wraped = new Err(msg, err.code, err)
wraped.stack = err.stack
return wraped
function isString (str) {
return typeof str == 'string'
}
module.exports = function (type, msg, code, orignalError) {
var Err = Errors.get(type)
if (!Err) return null
if (arguments.length === 1) {
if (util.isNumberLike(type)) {
return new Err()
} else {
return Err
}
} else {
code = Errors.ensureCode(code)
return new Err(msg, code, orignalError)
}
function isCode (code) {
return isNumber(code) && code >= 0 && code < 10000 || isString(code) && /^\d{1, 3}$/.test(code)
}
var apis = ['extend', 'wrap', 'configure']
apis.forEach(function (name) {
module.exports[name] = function () {
return Errors[name].apply(Errors, arguments)
}
})
var statusCodeMap = require('./httpStatusCode.json')
Object.keys(statusCodeMap).sort().forEach(function (key, ind) {
Errors.extend(key, +key, +key, '', statusCodeMap[key])
})
{
"name": "node-code-error",
"version": "0.1.42",
"version": "1.0.0",
"description": "define node error with code",

@@ -5,0 +5,0 @@ "main": "./index.js",

@@ -1,12 +0,9 @@

node-code-error
===
define errror with code
Introduction
====================
Validator Framework, write once and use anywhere.
[![NPM version][npm-image]][npm-url]
[![Build Status][travis-image]][travis-url]
## Installation
Install
-------------------
```bash
npm install node-code-error
$ npm install vfw
```

@@ -16,115 +13,240 @@

```js
// extend a new type of error
var CodeError = require('node-code-error')
CodeError.extend('api', 400, 100)
var err = CodeError('api', 'db is not defined', 32)
err.status // 400
err.toString() // 'ApiError: db is not defined'
err.toJSON()
/*
{
code: 10032,
message: 'ApiError: db is not defined',
type: 'ApiError'
var vfw = require('vfw')
// check object
var ruleSet = vfw.parse({
a: 'String:required',
b: 'Money'
})
ruleSet.check({a: 'as', b: 99}) // => true
ruleSet.check({a: 12, b: 'x.x'}) // => false
// check array
ruleSet = vfw.parse(['String', 'Moeny'])
ruleSet.check(['as',99]) // => true
ruleSet.check([123, 'x.x']) // => false
// check multidimensional array
ruleSet = vfw.parse({
$array: {
$array: 'String'
}
*/
})
ruleSet.check([['as'], ['ds']]) // => true
// configure CodeError and describe code by keywords
CodeError.configure({
maps: [{
user: 1,
book: 2,
cat: 3
}, {
missed: 1,
invalid: 2,
unmatched: 3
}],
splitLetter: ' ' // default is ' ',
useMsgForCode: true // default is false
// your can parse and check any js object
ruleSet = vfw.parse({
a: {
b: 'String'
c: ['Method', 'Url']
}
})
// then you can create err like this
err = CodeError('api', 'user invalid')
err.status // 400
err.toString() // 'ApiError: user invalid'
err.toJSON()
/*
{
code: 10012,
message: 'ApiError: user invalid',
type: 'ApiError'
ruleSet.check({a: {b: 'as', c: ['get', 'http://github.com']}})
// with logic element, $and ,$or and $xor is supported, and your can extend more
ruleSet = vfw.parse({
$or: {
a: 'String',
b: 'Moeny'
}
*/
})
ruleSet.check({a: 'as'}) // => true
ruleSet.check({a: 23, b: 12.2}) // => true
// with expression
ruleSet = vfw.parse({
a: {
$eq: 1
}
})
ruleSet.check({a: 1}) // => 1
// use without parse api
vfw.type('String', 'as') // => true
var a = 1
vfw.expression('eq', a, 1) // => true
// $ is short for expression
vfw.$('eq', a, 1) // => true
// everything in vfw is extendable
// extend your own type
vfw.extend('type', {
Word: function (str) {
return /^\w+$/.test(str)
}
})
vfw.type('Word', 'azAZ_09') // => true
ruleSet = vfw.parse({a: 'Word'})
ruleSet.check({a: 'azAZ_09'}) // => true
// extend your own expression
vfw.extend('expression', {
$gt: function (str, len) {
return str && str.length > len
}
})
var b = [1, 2]
vfw.$('gt', b, 1) // => true
ruleSet = vfw.parse({a: {$gt: 2}})
ruleSet.check({a: 'aas'}) // => true
// extend your own struct
vfw.extend('struct', 'User', {
name: 'Word:required',
// 类型 Word 长度 小于等于6
password: {
$type: 'Word',
$lte: 6
}
})
vfw.struct('User', {name: 'asd_123', password: 'asd_as'}) // => true
vfw.struct('User', {name: 'asd_123', password: 'asd_as123'}) // => false
vfw.struct('User', {password: 'ass123'}) // => false
```
## CLASS
### RuleType
- type, expression, struct are all intanceof RuleType, and you can extend your own RuleType by extendRule api.
* #### attributes
* _extended: `Object` store extended functions
* _includes: `Array` store included libs
* #### methods
* canHandle(rule)
* `required` check if the rule can be handled by this ruleType
* check(arr, rule)
* you can rewrite this function and check in aother way
* the first arguments is Array
* extend(obj)
* define how to extend
* include(lib)
* define how to include a lib
* get(key)
* get handler by key
* has(key)
### Rule
* #### attributes
* _name: `String` name of rule type
* _rule: rule object. for {a: 'String'}, _rule is 'String'
* _path: the path of the object. for {a: 'String'}, _path is 'a'
* _hdl: handler of this rule
* #### methods
* check(target)
* check the target
* clone()
* clone this rule
* addPath(path, depth)
* add a path to this rule.depth is default 0.
* setHandler(handler, rule)
* set _hdl and _rule
* finish()
* before add to struct, you should finish this rule first
### Struct
- collection of rules
* #### attributes
* uid `String` uniq id of this struct
* _rules `Array` array of rules
* _ruleMap `Object` map of rules
* #### methods
* add(rule) add a rule to this struct
* check(obj, opts) if opts.withErrors is true, check function will return [res, errs]
## API
### CodeError(name, msg, code, originalError)
- factory function for getting an error constructor or creating an instance
### vfw.type(Type, target)
```js
vfw.type('String', 'asd') // => true
vfw.type('Number', 'asd') // => false
```
### vfw.expression or vfw.$
```js
var CodeError = require('node-code-error')
CodeError.extend('api', 400, 100)
CodeError('api') // => function ApiError
CodeError('api', 'api error', 32, new Error('xxx')) // => instance of ApiError
vfw.$('in', [1, 2], 1) // => true
```
### CodeError.extend(name, status, baseCode, customCode)
### vfw.struct(StructName, target)
```js
vfw.struct('User', {user: 'lee', password: '123456'})
```
- `name` *Required*, `String`, define the type of the error
- `status` `Number`, define the status of the error, default is 500
- `baseCode` *Required*, `Number`, the first part of the code
- `customCode` *Option*, `Number`, if passed, the last part of code will be always the customCode, this is used for errors with stationary code, like SystemError
### vfw.extendRule(opts)
- extend your own RuleType. type, expression, struct are all instanceof RuleType.
```js
vfw.extendRule({
// canHandle function must be rewrited to tell vfw what it can handle
canHandle: function (obj) {
return /^@/.test(obj)
},
name: 'custom'
})
// if name supported
vfw.custom('@as', 12)
// and you can write rule like this
vfw.parse({
a: '@string'
})
```
### vfw.extendParser(Function)
```js
var CodeError = require('node-code-error')
CodeError.extend('api', 400, 100)
CodeError('api', 'api error', 43) // code == 10043
CodeError.extend('system', 500, 101, 10)
CodeError('system', 'system error', 43) // code == 10110
// extend a new RuleType, the rule '#xxx' will be handled by isXxx
// for example, #string will be handled by isString
vfw.extendParser(function (rule, struct, ruleIns) {
// if this function cant handle the rule, return false, and this rule will handled by others
if (!(typeof rule === 'string' && rule.charAt(0) === '#')) return false
rule = rule.slice(1)
rule = 'is' + rule.charAt(0).toUpperCase() + rule.slice(1)
var handler = vfw.get(rule)
if (!handler) return false
ruleIns.setHandler(handler, rule)
struct.add(ruleIns)
return true
})
var _ = require('lodash')
vfw.include('type', _)
// use _.isPlainObject
var struct = vfw.parse({a: '#PlainObject'})
struct.check({a: {a: 1}}) // => true
```
### CodeError.configure(opts)
- global config.only used for transfering message to code right now.
- maps `Array` map of values for keywords.for common use, you can use maps[0] as map of model, use maps[1] as map of action.then, your error message will like 'user invalid', 'password unmatch', etc.
### vfw.extend(type, extends)
- type `String` name of RuleType, like 'type', 'expression'
- extends `Object` the functions you want to extend
```js
var CodeError = require('node-code-error')
CodeError.configure({
maps: [{
user: 1,
book: 2,
cat: 3
}, {
missed: 1,
invalid: 2,
unmatch: 3
}],
splitLetter: ' ' // default is ' ',
useMsgForCode: true // default is false
vfw.extend('type', {
Money: function(){},
Url: function(){}
})
CodeError.extend('api', 400, 100)
var err = CodeError('api', 'use missed')
err.code // => 10011
var err = CodeError('api', 'book unmatch')
err.code // => 10023
vfw.extend('expression', {
$lt: function(target, len){},
$startWith: function(target, char){}
})
// once extended, those rules can be used anywhere
```
### CodeError.wrap(err, name)
- err *Required* `Error` the error to be wrapped
- name *Option* `String` which type of error to wrap, default is 'system'
### vfw.include(type, obj)
- type `String` name of RuleType, like 'type', 'expression'
- obj `Object`
- you can include a lib like lodash, validator or others and use the functions they supported
```js
var _ = require('lodash')
vfw.include('type', _)
// use _.isPlainObject
var struct = vfw.parse({a: '#PlainObject'})
struct.check({a: {a: 1}}) // => true
```
### vfw.parse(obj)
- parse a rule object and return an instance of Struct
```js
CodeError.extend('system', 500, 100, 10)
var err = new Error("I'm a nodejs Error")
var wrapped = CodeError.wrap(err, 'system')
wrapped.toString() // => "SystemError: I'm a nodejs Error"
wrapped.toJSON()
/*
=> {
code: 10010,
message: "SystemError: I'm a nodejs Error",
type: "SystemError"
}
*/
```
var rule = {
a: 'String:required',
b: 'Money'
}
var struct = vfw.parse(rule)
struct.check({a: 'as', b: 1.2}) // => true
```

@@ -9,3 +9,3 @@ 'use strict'

Object.keys(webHttpStatus).forEach(function (key) {
var err = CodeError(key)
var err = CodeError(+key)
assert(err.toJSON().code)

@@ -17,51 +17,21 @@ assert(err.toString())

it('extend', function () {
CodeError.extend('internal', 500, 101, 0)
var err = CodeError('internal', 'this is a internal error with default code')
assert(err.code === 1010)
assert(err.toString() === 'InternalError: this is a internal error with default code')
assert(err.toJSON().type === 'InternalError')
CodeError.extend('api', 400, 104)
err = CodeError('api', 'this is a internal error without default code', 62)
assert(err.code === 10462)
assert(err.toString() === 'ApiError: this is a internal error without default code')
assert(err.toJSON().type === 'ApiError')
})
it('configure', function () {
// use keywords to define code
CodeError.configure({
maps: [{
objectMap: {
user: 1,
alien: 2,
token: 3
}, {
},
actionMap: {
invalid: 1,
unmatch: 2,
missed: 3
}]
})
var err = CodeError('api', 'invalid user in xx api', 'user invalid')
assert(err.code === 10411)
assert(err.toString() === 'ApiError: invalid user in xx api')
assert(err.toJSON().type === 'ApiError')
// use msg for code
CodeError.configure({
useMsgForCode: true
})
err = CodeError('api', 'user invalid')
assert(err.code === 10411)
assert(err.toString() === 'ApiError: user invalid')
assert(err.toJSON().type === 'ApiError')
// config split letter
CodeError.configure({
splitLetter: ',',
useMsgForCode: false
})
err = CodeError('api', 'invalid user in xx api', 'user,invalid')
assert(err.code === 10411)
assert(err.toString() === 'ApiError: invalid user in xx api')
assert(err.toJSON().type === 'ApiError')
// config additionKeys
CodeError.configure({
},
typeMap: {
api: {
typeCode: 104,
status: 400
}
},
additionKeys: ['action', 'refer'],

@@ -74,3 +44,8 @@ i18n: {

})
err = CodeError('api', 'invalid user in xx api', 11)
var err = CodeError('api', 'user invalid')
assert(err.code === 10411)
console.log(err.toString())
assert(err.toString() === 'api error: user invalid')
assert(err.toJSON().type === 'api')
err = CodeError('api', 'user invalid')
var localeJson = err.toLocaleJSON({action: 'create', refer: 'github'})

@@ -82,1 +57,8 @@ assert(localeJson.message === '创建Github账户失败')

})
it('extend', function () {
CodeError.extend('internal', 500, 101, 10, 10)
var err = CodeError('internal')
assert(err.code === 1011010)
assert(err.toJSON().type === 'internal')
})
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