'clientError' 事件


如果客户端连接触发 'error' 事件,则会在此处转发。 此事件的监听器负责关闭/销毁底层套接字。 例如,可能希望使用自定义 HTTP 响应更优雅地关闭套接字,而不是突然切断连接。

除非用户指定 <net.Socket> 以外的套接字类型,否则此事件保证传入 <net.Socket> 类(<stream.Duplex> 的子类)的实例。

默认行为是在 HPE_HEADER_OVERFLOW 错误的情况下尝试使用 HTTP '400 Bad Request' 或 HTTP '431 Request Header Fields Too Large' 关闭套接字。 如果套接字不可写或已经写入数据,则会立即被销毁。

socket 是错误源自的 net.Socket 对象。

const http = require('node:http');

const server = http.createServer((req, res) => {
  res.end();
});
server.on('clientError', (err, socket) => {
  socket.end('HTTP/1.1 400 Bad Request\r\n\r\n');
});
server.listen(8000);

'clientError' 事件发生时,没有 requestresponse 对象,因此发送的任何 HTTP 响应,包括响应头和有效负载,都必须直接写入 socket 对象。 必须注意确保响应是格式正确的 HTTP 响应消息。

errError 的实例,有两个额外的列:

  • bytesParsed: Node.js 可能正确解析的请求数据包的字节数;
  • rawPacket: 当前请求的原始数据包。

在某些情况下,客户端已经收到响应和/或套接字已经被销毁,例如 ECONNRESET 错误。 在尝试向套接字发送数据之前,最好检查它是否仍然可写。

server.on('clientError', (err, socket) => {
  if (err.code === 'ECONNRESET' || !socket.writable) {
    return;
  }

  socket.end('HTTP/1.1 400 Bad Request\r\n\r\n');
});

If a client connection emits an 'error' event, it will be forwarded here. Listener of this event is responsible for closing/destroying the underlying socket. For example, one may wish to more gracefully close the socket with a custom HTTP response instead of abruptly severing the connection.

This event is guaranteed to be passed an instance of the <net.Socket> class, a subclass of <stream.Duplex>, unless the user specifies a socket type other than <net.Socket>.

Default behavior is to try close the socket with a HTTP '400 Bad Request', or a HTTP '431 Request Header Fields Too Large' in the case of a HPE_HEADER_OVERFLOW error. If the socket is not writable or has already written data it is immediately destroyed.

socket is the net.Socket object that the error originated from.

const http = require('node:http');

const server = http.createServer((req, res) => {
  res.end();
});
server.on('clientError', (err, socket) => {
  socket.end('HTTP/1.1 400 Bad Request\r\n\r\n');
});
server.listen(8000);

When the 'clientError' event occurs, there is no request or response object, so any HTTP response sent, including response headers and payload, must be written directly to the socket object. Care must be taken to ensure the response is a properly formatted HTTP response message.

err is an instance of Error with two extra columns:

  • bytesParsed: the bytes count of request packet that Node.js may have parsed correctly;
  • rawPacket: the raw packet of current request.

In some cases, the client has already received the response and/or the socket has already been destroyed, like in case of ECONNRESET errors. Before trying to send data to the socket, it is better to check that it is still writable.

server.on('clientError', (err, socket) => {
  if (err.code === 'ECONNRESET' || !socket.writable) {
    return;
  }

  socket.end('HTTP/1.1 400 Bad Request\r\n\r\n');
});