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

Don't wrap existing errors #37

Merged
merged 8 commits into from
Sep 24, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Don't wrap existing errors
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
commit 8c2de6b5561f6df9717f09ecddd24f8b8381b0a8
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
juliangruber marked this conversation as resolved.
Show resolved Hide resolved

// 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()
})