Skip to content

Commit c0bda46

Browse files
committed
Add BaseError.httpResponse()
1 parent 926dfcf commit c0bda46

File tree

6 files changed

+63
-41
lines changed

6 files changed

+63
-41
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
# 2.2.0
2+
3+
## Features
4+
5+
- `error.httpResponse()` has been renamed to
6+
[`BaseError.httpResponse(error)`](README.md#baseerrorhttpresponseerror).
7+
`error.httpResponse()` is deprecated but still supported.
8+
19
# 2.1.0
210

311
## Features

README.md

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,10 @@
1515
[plugin](https://github.com/ehmicky/modern-errors#-plugins) to create HTTP error
1616
responses.
1717

18-
This adds [`error.httpResponse()`](#errorhttpresponse) which converts `error` to
19-
a plain object ([RFC 7807](https://www.rfc-editor.org/rfc/rfc7807), "problem
20-
details") to use in an HTTP response.
18+
This adds [`BaseError.httpResponse(error)`](#baseerrorhttpresponseerror) which
19+
converts `error` to a plain object
20+
([RFC 7807](https://www.rfc-editor.org/rfc/rfc7807), "problem details") to use
21+
in an HTTP response.
2122

2223
# Example
2324

@@ -44,7 +45,7 @@ export const AuthError = BaseError.subclass('AuthError', {
4445
})
4546
```
4647

47-
[Creating](#errorhttpresponse) an HTTP error response.
48+
[Creating](#baseerrorhttpresponseerror) an HTTP error response.
4849

4950
```js
5051
const error = new AuthError('Could not authenticate.', {
@@ -53,7 +54,7 @@ const error = new AuthError('Could not authenticate.', {
5354
extra: { userId: 62 },
5455
},
5556
})
56-
const object = error.httpResponse()
57+
const object = BaseError.httpResponse(error)
5758
// {
5859
// type: 'https://example.com/probs/auth',
5960
// status: 401,
@@ -88,7 +89,9 @@ Plugin object to pass to the
8889
[`plugins` option](https://github.com/ehmicky/modern-errors#adding-plugins) of
8990
`ErrorClass.subclass()`.
9091

91-
## error.httpResponse()
92+
## BaseError.httpResponse(error)
93+
94+
`error`: `Error`
9295

9396
_Return value_: `HttpResponse`
9497

@@ -181,10 +184,10 @@ export const AuthError = BaseError.subclass('AuthError', {
181184
throw new AuthError('...', { http: { ...options } })
182185
```
183186

184-
- A specific [`error.httpResponse()`](#errorhttpresponse) call
187+
- A specific [`BaseError.httpResponse(error)`](#baseerrorhttpresponseerror) call
185188

186189
```js
187-
error.httpResponse(...args, { ...options })
190+
BaseError.httpResponse(error, ...args, { ...options })
188191
```
189192

190193
# Related projects

test/main.js

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ each(
2121
],
2222
({ title }, [propName, propValue]) => {
2323
test(`Valid options are kept | ${title}`, (t) => {
24-
const httpResponse = baseError.httpResponse({ [propName]: propValue })
24+
const httpResponse = BaseError.httpResponse(baseError, {
25+
[propName]: propValue,
26+
})
2527
t.deepEqual(httpResponse[propName], propValue)
2628
})
2729
},
@@ -35,30 +37,36 @@ each(
3537
(optName) => ({ [optName]: undefined }),
3638
),
3739
],
38-
({ title }, http) => {
40+
({ title }, options) => {
3941
test(`Assign default options | ${title}`, (t) => {
4042
const { name, message, stack } = baseError
41-
const httpResponse = baseError.httpResponse(http)
43+
const httpResponse = BaseError.httpResponse(baseError, options)
4244
t.deepEqual(httpResponse, { title: name, detail: message, stack })
4345
})
4446
},
4547
)
4648

49+
test('Can be called as error.httpResponse()', (t) => {
50+
t.is(BaseError.httpResponse(baseError).title, baseError.name)
51+
})
52+
4753
test('Assign default extra', (t) => {
4854
const props = { prop: true }
49-
t.deepEqual(new BaseError('test', { props }).httpResponse().extra, props)
55+
const error = new BaseError('test', { props })
56+
t.deepEqual(BaseError.httpResponse(error).extra, props)
5057
})
5158

5259
test('Keep extra JSON-safe', (t) => {
53-
t.deepEqual(baseError.httpResponse({ extra: { one: true, two: 0n } }).extra, {
54-
one: true,
55-
})
60+
t.deepEqual(
61+
BaseError.httpResponse(baseError, { extra: { one: true, two: 0n } }).extra,
62+
{ one: true },
63+
)
5664
})
5765

5866
test('Keep object keys order', (t) => {
5967
t.deepEqual(
6068
Object.keys(
61-
baseError.httpResponse({
69+
BaseError.httpResponse(baseError, {
6270
extra: {},
6371
stack: '',
6472
instance: '',

test/options.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import test from 'ava'
22
import { each } from 'test-each'
33

4-
import { baseError } from './helpers/main.js'
4+
import { BaseError, baseError } from './helpers/main.js'
55

66
each(
77
[
@@ -18,9 +18,9 @@ each(
1818
]),
1919
{ extra: true },
2020
],
21-
({ title }, http) => {
21+
({ title }, options) => {
2222
test(`Options are validated | ${title}`, (t) => {
23-
t.throws(baseError.httpResponse.bind(baseError, http))
23+
t.throws(BaseError.httpResponse.bind(undefined, baseError, options))
2424
})
2525
},
2626
)

types/main.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ export interface Options {
5858
}
5959

6060
/**
61-
* `error.httpResponse()`'s return value
61+
* `BaseError.httpResponse(error)`'s return value
6262
*/
6363
export interface HttpResponse extends Options {
6464
readonly title: string
@@ -80,7 +80,7 @@ declare const plugin: {
8080
*
8181
* @example
8282
* ```js
83-
* const object = error.httpResponse()
83+
* const object = BaseError.httpResponse(error)
8484
* // {
8585
* // type: 'https://example.com/probs/auth',
8686
* // status: 401,

types/main.test-d.ts

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,115 +9,115 @@ import {
99

1010
const BaseError = ModernError.subclass('BaseError', { plugins: [plugin] })
1111
const error = new BaseError('')
12-
const httpResponse = error.httpResponse()
12+
const httpResponse = BaseError.httpResponse(error)
1313

1414
ModernError.subclass('TestError', { plugins: [plugin], http: {} })
15-
error.httpResponse({})
15+
BaseError.httpResponse(error, {})
1616
expectAssignable<Options>({})
17-
expectError(error.httpResponse(undefined))
17+
expectError(BaseError.httpResponse(error, undefined))
1818
expectNotAssignable<Options>(undefined)
1919
expectError(
2020
ModernError.subclass('TestError', { plugins: [plugin], http: true }),
2121
)
22-
expectError(error.httpResponse(true))
22+
expectError(BaseError.httpResponse(error, true))
2323
expectNotAssignable<Options>(true)
2424
expectError(
2525
ModernError.subclass('TestError', {
2626
plugins: [plugin],
2727
http: { unknown: true },
2828
}),
2929
)
30-
expectError(error.httpResponse({ unknown: true }))
30+
expectError(BaseError.httpResponse(error, { unknown: true }))
3131
expectNotAssignable<Options>({ unknown: true })
3232

3333
ModernError.subclass('TestError', { plugins: [plugin], http: { type: '' } })
34-
error.httpResponse({ type: '' })
34+
BaseError.httpResponse(error, { type: '' })
3535
expectAssignable<Options>({ type: '' })
3636
expectError(
3737
ModernError.subclass('TestError', {
3838
plugins: [plugin],
3939
http: { type: true },
4040
}),
4141
)
42-
expectError(error.httpResponse({ type: true }))
42+
expectError(BaseError.httpResponse(error, { type: true }))
4343
expectNotAssignable<Options>({ type: true })
4444

4545
ModernError.subclass('TestError', { plugins: [plugin], http: { status: 200 } })
46-
error.httpResponse({ status: 200 })
46+
BaseError.httpResponse(error, { status: 200 })
4747
expectAssignable<Options>({ status: 200 })
4848
expectError(
4949
ModernError.subclass('TestError', {
5050
plugins: [plugin],
5151
http: { status: true },
5252
}),
5353
)
54-
expectError(error.httpResponse({ status: true }))
54+
expectError(BaseError.httpResponse(error, { status: true }))
5555
expectNotAssignable<Options>({ status: true })
5656

5757
ModernError.subclass('TestError', { plugins: [plugin], http: { title: '' } })
58-
error.httpResponse({ title: '' })
58+
BaseError.httpResponse(error, { title: '' })
5959
expectAssignable<Options>({ title: '' })
6060
expectError(
6161
ModernError.subclass('TestError', {
6262
plugins: [plugin],
6363
http: { title: true },
6464
}),
6565
)
66-
expectError(error.httpResponse({ title: true }))
66+
expectError(BaseError.httpResponse(error, { title: true }))
6767
expectNotAssignable<Options>({ title: true })
6868

6969
ModernError.subclass('TestError', { plugins: [plugin], http: { detail: '' } })
70-
error.httpResponse({ detail: '' })
70+
BaseError.httpResponse(error, { detail: '' })
7171
expectAssignable<Options>({ detail: '' })
7272
expectError(
7373
ModernError.subclass('TestError', {
7474
plugins: [plugin],
7575
http: { detail: true },
7676
}),
7777
)
78-
expectError(error.httpResponse({ detail: true }))
78+
expectError(BaseError.httpResponse(error, { detail: true }))
7979
expectNotAssignable<Options>({ detail: true })
8080

8181
ModernError.subclass('TestError', { plugins: [plugin], http: { instance: '' } })
82-
error.httpResponse({ instance: '' })
82+
BaseError.httpResponse(error, { instance: '' })
8383
expectAssignable<Options>({ instance: '' })
8484
expectError(
8585
ModernError.subclass('TestError', {
8686
plugins: [plugin],
8787
http: { instance: true },
8888
}),
8989
)
90-
expectError(error.httpResponse({ instance: true }))
90+
expectError(BaseError.httpResponse(error, { instance: true }))
9191
expectNotAssignable<Options>({ instance: true })
9292

9393
ModernError.subclass('TestError', { plugins: [plugin], http: { stack: '' } })
94-
error.httpResponse({ stack: '' })
94+
BaseError.httpResponse(error, { stack: '' })
9595
expectAssignable<Options>({ stack: '' })
9696
expectError(
9797
ModernError.subclass('TestError', {
9898
plugins: [plugin],
9999
http: { stack: true },
100100
}),
101101
)
102-
expectError(error.httpResponse({ stack: true }))
102+
expectError(BaseError.httpResponse(error, { stack: true }))
103103
expectNotAssignable<Options>({ stack: true })
104104

105105
ModernError.subclass('TestError', { plugins: [plugin], http: { extra: {} } })
106-
error.httpResponse({ extra: {} })
106+
BaseError.httpResponse(error, { extra: {} })
107107
expectAssignable<Options>({ extra: {} })
108108
ModernError.subclass('TestError', {
109109
plugins: [plugin],
110110
http: { extra: { prop: true } },
111111
})
112-
error.httpResponse({ extra: { prop: true } })
112+
BaseError.httpResponse(error, { extra: { prop: true } })
113113
expectAssignable<Options>({ extra: { prop: true } })
114114
expectError(
115115
ModernError.subclass('TestError', {
116116
plugins: [plugin],
117117
http: { extra: true },
118118
}),
119119
)
120-
expectError(error.httpResponse({ extra: true }))
120+
expectError(BaseError.httpResponse(error, { extra: true }))
121121
expectNotAssignable<Options>({ extra: true })
122122

123123
expectType<HttpResponse>(httpResponse)
@@ -129,3 +129,6 @@ expectType<string | undefined>(httpResponse.instance)
129129
expectType<string>(httpResponse.stack)
130130
expectType<object | undefined>(httpResponse.extra)
131131
expectError(httpResponse.extra?.prop)
132+
133+
expectType<HttpResponse>(error.httpResponse())
134+
expectError(error.httpResponse(true))

0 commit comments

Comments
 (0)