Skip to content
This repository has been archived by the owner on Dec 20, 2024. It is now read-only.

Commit

Permalink
Don't wrap existing errors
Browse files Browse the repository at this point in the history
So that when `abstract-leveldown` starts using `level-errors`, and
such a db is wrapped with `levelup`, `levelup` will not rewrap
errors and lose stack trace information in the process. I.e.:

```
// Error created by abstract-leveldown
const err = new ReadError('example')

// Error created by levelup
const wrapped = new ReadError(err)

assert(wrapped === err)
```

Ref Level/community#58
  • Loading branch information
vweevers committed Sep 18, 2021
1 parent 6db33c7 commit 8c2de6b
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 2 deletions.
13 changes: 11 additions & 2 deletions errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,25 @@

function createError (type, Proto) {
const Err = function (message, cause) {
if (message && typeof message !== 'string') {
if (typeof message === 'object' && message !== null) {
// Can be passed just a cause
cause = cause || message
message = message.message || message.name
}

message = message || ''
cause = cause || undefined

// If input is already of type, return as-is to keep its stack trace.
// Avoid instanceof, for when node_modules has multiple copies of level-errors.
if (typeof cause === 'object' && cause.type === type && cause.message === message) {
return cause
}

Object.defineProperty(this, 'type', { value: type, enumerable: false, writable: true, configurable: true })
Object.defineProperty(this, 'name', { value: type, enumerable: false, writable: true, configurable: true })
Object.defineProperty(this, 'cause', { value: cause, enumerable: false, writable: true, configurable: true })
Object.defineProperty(this, 'message', { value: message || '', enumerable: false, writable: true, configurable: true })
Object.defineProperty(this, 'message', { value: message, enumerable: false, writable: true, configurable: true })

Error.call(this)

Expand Down
30 changes: 30 additions & 0 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,33 @@ test('error message is writable for flexibility', function (t) {
t.is(error.message, 'Got error: foo')
t.end()
})

test('returns original instance if cause is the same type', function (t) {
const cause = new errors.NotFoundError('Key not found in database [foo]')
const error = new errors.NotFoundError(cause)
t.ok(cause === error, 'same instance')
t.is(error.message, 'Key not found in database [foo]')
t.end()
})

test('returns new instance if cause prototype is different', function (t) {
const cause = new errors.NotFoundError('Key not found in database [foo]')
const error = new errors.WriteError(cause)
t.ok(cause !== error, 'new instance')
t.is(error.message, 'Key not found in database [foo]')
t.end()
})

test('returns original instance if message and cause are the same', function (t) {
const cause = new errors.NotFoundError('Key not found in database [foo]')
const error = new errors.NotFoundError('Key not found in database [foo]', cause)
t.ok(cause === error, 'same instance')
t.end()
})

test('returns new instance if message is different', function (t) {
const cause = new errors.NotFoundError('Key not found in database [foo]')
const error = new errors.NotFoundError('Key not found in database [bar]', cause)
t.ok(cause !== error, 'new instance')
t.end()
})

0 comments on commit 8c2de6b

Please sign in to comment.