Skip to content

Commit de9c40b

Browse files
Filippo Contimastermatt
authored andcommitted
feat(socket): propagate errors from destroy method (#1675)
Calling `destroy` on the the response, with an error, not correctly propagates through the socket and then the request object. This aligns with Node's native functionality. Fixes: #1669
1 parent 2e56fb0 commit de9c40b

File tree

3 files changed

+49
-2
lines changed

3 files changed

+49
-2
lines changed

lib/request_overrider.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ class InterceptedRequestHandler {
124124
this.response.socket = this.response.client = this.response.connection =
125125
req.socket
126126

127-
propagate(['timeout'], req.socket, req)
127+
propagate(['error', 'timeout'], req.socket, req)
128128

129129
req.write = (...args) => this.handleWrite(...args)
130130
req.end = (...args) => this.handleEnd(...args)

lib/socket.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,12 @@ module.exports = class Socket extends EventEmitter {
5454
).toString('base64')
5555
}
5656

57-
destroy() {
57+
destroy(err) {
5858
this.destroyed = true
5959
this.readable = this.writable = false
60+
if (err) {
61+
this.emit('error', err)
62+
}
63+
return this
6064
}
6165
}

tests/test_destroy.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
'use strict'
2+
3+
const nock = require('..')
4+
const http = require('http')
5+
const { test } = require('tap')
6+
7+
require('./cleanup_after_each')()
8+
9+
test('req.destroy should emit error event if called with error', t => {
10+
nock('http://example.test')
11+
.get('/')
12+
.reply(404)
13+
14+
http
15+
.get('http://example.test/', res => {
16+
if (res.statusCode !== 200) {
17+
res.destroy(new Error('Response error'))
18+
}
19+
})
20+
.once('error', err => {
21+
t.type(err, Error)
22+
t.equal(err.message, 'Response error')
23+
t.end()
24+
})
25+
})
26+
27+
test('req.destroy should not emit error event if called without error', t => {
28+
nock('http://example.test')
29+
.get('/')
30+
.reply(403)
31+
32+
http
33+
.get('http://example.test/', res => {
34+
if (res.statusCode === 403) {
35+
res.destroy()
36+
}
37+
38+
t.end()
39+
})
40+
.once('error', () => {
41+
t.fail('should not emit error')
42+
})
43+
})

0 commit comments

Comments
 (0)