This commit is contained in:
Tutur33
2023-11-24 22:35:41 +01:00
parent 3c0b507a93
commit 7644b2a0f7
45165 changed files with 4803356 additions and 3 deletions
+203
View File
@@ -0,0 +1,203 @@
'use strict'
const test = require('tap').test
const serializer = require('../lib/err-with-cause')
const wrapErrorSerializer = require('../').wrapErrorSerializer
test('serializes Error objects', function (t) {
t.plan(3)
const serialized = serializer(Error('foo'))
t.equal(serialized.type, 'Error')
t.equal(serialized.message, 'foo')
t.match(serialized.stack, /err-with-cause\.test\.js:/)
})
test('serializes Error objects with extra properties', function (t) {
t.plan(5)
const err = Error('foo')
err.statusCode = 500
const serialized = serializer(err)
t.equal(serialized.type, 'Error')
t.equal(serialized.message, 'foo')
t.ok(serialized.statusCode)
t.equal(serialized.statusCode, 500)
t.match(serialized.stack, /err-with-cause\.test\.js:/)
})
test('serializes Error objects with subclass "type"', function (t) {
t.plan(1)
class MyError extends Error {}
const err = new MyError('foo')
const serialized = serializer(err)
t.equal(serialized.type, 'MyError')
})
test('serializes nested errors', function (t) {
t.plan(7)
const err = Error('foo')
err.inner = Error('bar')
const serialized = serializer(err)
t.equal(serialized.type, 'Error')
t.equal(serialized.message, 'foo')
t.match(serialized.stack, /err-with-cause\.test\.js:/)
t.equal(serialized.inner.type, 'Error')
t.equal(serialized.inner.message, 'bar')
t.match(serialized.inner.stack, /Error: bar/)
t.match(serialized.inner.stack, /err-with-cause\.test\.js:/)
})
test('serializes error causes', function (t) {
const innerErr = Error('inner')
const middleErr = Error('middle')
middleErr.cause = innerErr
const outerErr = Error('outer')
outerErr.cause = middleErr
const serialized = serializer(outerErr)
t.equal(serialized.type, 'Error')
t.equal(serialized.message, 'outer')
t.match(serialized.stack, /err-with-cause\.test\.js:/)
t.equal(serialized.cause.type, 'Error')
t.equal(serialized.cause.message, 'middle')
t.match(serialized.cause.stack, /err-with-cause\.test\.js:/)
t.equal(serialized.cause.cause.type, 'Error')
t.equal(serialized.cause.cause.message, 'inner')
t.match(serialized.cause.cause.stack, /err-with-cause\.test\.js:/)
t.end()
})
test('keeps non-error cause', function (t) {
t.plan(3)
const err = Error('foo')
err.cause = 'abc'
const serialized = serializer(err)
t.equal(serialized.type, 'Error')
t.equal(serialized.message, 'foo')
t.equal(serialized.cause, 'abc')
})
test('prevents infinite recursion', function (t) {
t.plan(4)
const err = Error('foo')
err.inner = err
const serialized = serializer(err)
t.equal(serialized.type, 'Error')
t.equal(serialized.message, 'foo')
t.match(serialized.stack, /err-with-cause\.test\.js:/)
t.notOk(serialized.inner)
})
test('cleans up infinite recursion tracking', function (t) {
t.plan(8)
const err = Error('foo')
const bar = Error('bar')
err.inner = bar
bar.inner = err
serializer(err)
const serialized = serializer(err)
t.equal(serialized.type, 'Error')
t.equal(serialized.message, 'foo')
t.match(serialized.stack, /err-with-cause\.test\.js:/)
t.ok(serialized.inner)
t.equal(serialized.inner.type, 'Error')
t.equal(serialized.inner.message, 'bar')
t.match(serialized.inner.stack, /Error: bar/)
t.notOk(serialized.inner.inner)
})
test('err.raw is available', function (t) {
t.plan(1)
const err = Error('foo')
const serialized = serializer(err)
t.equal(serialized.raw, err)
})
test('redefined err.constructor doesnt crash serializer', function (t) {
t.plan(10)
function check (a, name) {
t.equal(a.type, name)
t.equal(a.message, 'foo')
}
const err1 = TypeError('foo')
err1.constructor = '10'
const err2 = TypeError('foo')
err2.constructor = undefined
const err3 = Error('foo')
err3.constructor = null
const err4 = Error('foo')
err4.constructor = 10
class MyError extends Error {}
const err5 = new MyError('foo')
err5.constructor = undefined
check(serializer(err1), 'TypeError')
check(serializer(err2), 'TypeError')
check(serializer(err3), 'Error')
check(serializer(err4), 'Error')
// We do not expect 'MyError' because err5.constructor has been blown away.
// `err5.name` is 'Error' from the base class prototype.
check(serializer(err5), 'Error')
})
test('pass through anything that does not look like an Error', function (t) {
t.plan(3)
function check (a) {
t.equal(serializer(a), a)
}
check('foo')
check({ hello: 'world' })
check([1, 2])
})
test('can wrap err serializers', function (t) {
t.plan(5)
const err = Error('foo')
err.foo = 'foo'
const serializer = wrapErrorSerializer(function (err) {
delete err.foo
err.bar = 'bar'
return err
})
const serialized = serializer(err)
t.equal(serialized.type, 'Error')
t.equal(serialized.message, 'foo')
t.match(serialized.stack, /err-with-cause\.test\.js:/)
t.notOk(serialized.foo)
t.equal(serialized.bar, 'bar')
})
test('serializes aggregate errors', { skip: !global.AggregateError }, function (t) {
t.plan(14)
const foo = new Error('foo')
const bar = new Error('bar')
for (const aggregate of [
new AggregateError([foo, bar], 'aggregated message'), // eslint-disable-line no-undef
{ errors: [foo, bar], message: 'aggregated message', stack: 'err-with-cause.test.js:' }
]) {
const serialized = serializer(aggregate)
t.equal(serialized.message, 'aggregated message')
t.equal(serialized.aggregateErrors.length, 2)
t.equal(serialized.aggregateErrors[0].message, 'foo')
t.equal(serialized.aggregateErrors[1].message, 'bar')
t.match(serialized.aggregateErrors[0].stack, /^Error: foo/)
t.match(serialized.aggregateErrors[1].stack, /^Error: bar/)
t.match(serialized.stack, /err-with-cause\.test\.js:/)
}
})
+215
View File
@@ -0,0 +1,215 @@
'use strict'
const test = require('tap').test
const serializer = require('../lib/err')
const wrapErrorSerializer = require('../').wrapErrorSerializer
test('serializes Error objects', function (t) {
t.plan(3)
const serialized = serializer(Error('foo'))
t.equal(serialized.type, 'Error')
t.equal(serialized.message, 'foo')
t.match(serialized.stack, /err\.test\.js:/)
})
test('serializes Error objects with extra properties', function (t) {
t.plan(5)
const err = Error('foo')
err.statusCode = 500
const serialized = serializer(err)
t.equal(serialized.type, 'Error')
t.equal(serialized.message, 'foo')
t.ok(serialized.statusCode)
t.equal(serialized.statusCode, 500)
t.match(serialized.stack, /err\.test\.js:/)
})
test('serializes Error objects with subclass "type"', function (t) {
t.plan(1)
class MyError extends Error {}
const err = new MyError('foo')
const serialized = serializer(err)
t.equal(serialized.type, 'MyError')
})
test('serializes nested errors', function (t) {
t.plan(7)
const err = Error('foo')
err.inner = Error('bar')
const serialized = serializer(err)
t.equal(serialized.type, 'Error')
t.equal(serialized.message, 'foo')
t.match(serialized.stack, /err\.test\.js:/)
t.equal(serialized.inner.type, 'Error')
t.equal(serialized.inner.message, 'bar')
t.match(serialized.inner.stack, /Error: bar/)
t.match(serialized.inner.stack, /err\.test\.js:/)
})
test('serializes error causes', function (t) {
t.plan(14)
for (const cause of [
Error('bar'),
{ message: 'bar', stack: 'Error: bar: err.test.js:' }
]) {
const err = Error('foo')
err.cause = cause
err.cause.cause = Error('abc')
const serialized = serializer(err)
t.equal(serialized.type, 'Error')
t.equal(serialized.message, 'foo: bar: abc')
t.match(serialized.stack, /err\.test\.js:/)
t.match(serialized.stack, /Error: foo/)
t.match(serialized.stack, /Error: bar/)
t.match(serialized.stack, /Error: abc/)
t.notOk(serialized.cause)
}
})
test('serializes error causes with VError support', function (t) {
t.plan(6)
// Fake VError-style setup
const err = Error('foo: bar')
err.foo = 'abc'
err.cause = function () {
const err = Error('bar')
err.cause = Error(this.foo)
return err
}
const serialized = serializer(err)
t.equal(serialized.type, 'Error')
t.equal(serialized.message, 'foo: bar: abc')
t.match(serialized.stack, /err\.test\.js:/)
t.match(serialized.stack, /Error: foo/)
t.match(serialized.stack, /Error: bar/)
t.match(serialized.stack, /Error: abc/)
})
test('keeps non-error cause', function (t) {
t.plan(3)
const err = Error('foo')
err.cause = 'abc'
const serialized = serializer(err)
t.equal(serialized.type, 'Error')
t.equal(serialized.message, 'foo')
t.equal(serialized.cause, 'abc')
})
test('prevents infinite recursion', function (t) {
t.plan(4)
const err = Error('foo')
err.inner = err
const serialized = serializer(err)
t.equal(serialized.type, 'Error')
t.equal(serialized.message, 'foo')
t.match(serialized.stack, /err\.test\.js:/)
t.notOk(serialized.inner)
})
test('cleans up infinite recursion tracking', function (t) {
t.plan(8)
const err = Error('foo')
const bar = Error('bar')
err.inner = bar
bar.inner = err
serializer(err)
const serialized = serializer(err)
t.equal(serialized.type, 'Error')
t.equal(serialized.message, 'foo')
t.match(serialized.stack, /err\.test\.js:/)
t.ok(serialized.inner)
t.equal(serialized.inner.type, 'Error')
t.equal(serialized.inner.message, 'bar')
t.match(serialized.inner.stack, /Error: bar/)
t.notOk(serialized.inner.inner)
})
test('err.raw is available', function (t) {
t.plan(1)
const err = Error('foo')
const serialized = serializer(err)
t.equal(serialized.raw, err)
})
test('redefined err.constructor doesnt crash serializer', function (t) {
t.plan(10)
function check (a, name) {
t.equal(a.type, name)
t.equal(a.message, 'foo')
}
const err1 = TypeError('foo')
err1.constructor = '10'
const err2 = TypeError('foo')
err2.constructor = undefined
const err3 = Error('foo')
err3.constructor = null
const err4 = Error('foo')
err4.constructor = 10
class MyError extends Error {}
const err5 = new MyError('foo')
err5.constructor = undefined
check(serializer(err1), 'TypeError')
check(serializer(err2), 'TypeError')
check(serializer(err3), 'Error')
check(serializer(err4), 'Error')
// We do not expect 'MyError' because err5.constructor has been blown away.
// `err5.name` is 'Error' from the base class prototype.
check(serializer(err5), 'Error')
})
test('pass through anything that does not look like an Error', function (t) {
t.plan(3)
function check (a) {
t.equal(serializer(a), a)
}
check('foo')
check({ hello: 'world' })
check([1, 2])
})
test('can wrap err serializers', function (t) {
t.plan(5)
const err = Error('foo')
err.foo = 'foo'
const serializer = wrapErrorSerializer(function (err) {
delete err.foo
err.bar = 'bar'
return err
})
const serialized = serializer(err)
t.equal(serialized.type, 'Error')
t.equal(serialized.message, 'foo')
t.match(serialized.stack, /err\.test\.js:/)
t.notOk(serialized.foo)
t.equal(serialized.bar, 'bar')
})
test('serializes aggregate errors', { skip: !global.AggregateError }, function (t) {
t.plan(14)
const foo = new Error('foo')
const bar = new Error('bar')
for (const aggregate of [
new AggregateError([foo, bar], 'aggregated message'), // eslint-disable-line no-undef
{ errors: [foo, bar], message: 'aggregated message', stack: 'err.test.js:' }
]) {
const serialized = serializer(aggregate)
t.equal(serialized.message, 'aggregated message')
t.equal(serialized.aggregateErrors.length, 2)
t.equal(serialized.aggregateErrors[0].message, 'foo')
t.equal(serialized.aggregateErrors[1].message, 'bar')
t.match(serialized.aggregateErrors[0].stack, /^Error: foo/)
t.match(serialized.aggregateErrors[1].stack, /^Error: bar/)
t.match(serialized.stack, /err\.test\.js:/)
}
})
+433
View File
@@ -0,0 +1,433 @@
'use strict'
const http = require('http')
const test = require('tap').test
const serializers = require('../lib/req')
const wrapRequestSerializer = require('../').wrapRequestSerializer
test('maps request', function (t) {
t.plan(2)
const server = http.createServer(handler)
server.unref()
server.listen(0, () => {
http.get(server.address(), () => {})
})
t.teardown(() => server.close())
function handler (req, res) {
const serialized = serializers.mapHttpRequest(req)
t.ok(serialized.req)
t.ok(serialized.req.method)
t.end()
res.end()
}
})
test('does not return excessively long object', function (t) {
t.plan(1)
const server = http.createServer(handler)
server.unref()
server.listen(0, () => {
http.get(server.address(), () => {})
})
t.teardown(() => server.close())
function handler (req, res) {
const serialized = serializers.reqSerializer(req)
t.equal(Object.keys(serialized).length, 6)
res.end()
}
})
test('req.raw is available', function (t) {
t.plan(2)
const server = http.createServer(handler)
server.unref()
server.listen(0, () => {
http.get(server.address(), () => {})
})
t.teardown(() => server.close())
function handler (req, res) {
req.foo = 'foo'
const serialized = serializers.reqSerializer(req)
t.ok(serialized.raw)
t.equal(serialized.raw.foo, 'foo')
res.end()
}
})
test('req.raw will be obtained in from input request raw property if input request raw property is truthy', function (t) {
t.plan(2)
const server = http.createServer(handler)
server.unref()
server.listen(0, () => {
http.get(server.address(), () => {})
})
t.teardown(() => server.close())
function handler (req, res) {
req.raw = { req: { foo: 'foo' }, res: {} }
const serialized = serializers.reqSerializer(req)
t.ok(serialized.raw)
t.equal(serialized.raw.req.foo, 'foo')
res.end()
}
})
test('req.id defaults to undefined', function (t) {
t.plan(1)
const server = http.createServer(handler)
server.unref()
server.listen(0, () => {
http.get(server.address(), () => {})
})
t.teardown(() => server.close())
function handler (req, res) {
const serialized = serializers.reqSerializer(req)
t.equal(serialized.id, undefined)
res.end()
}
})
test('req.id has a non-function value', function (t) {
t.plan(1)
const server = http.createServer(handler)
server.unref()
server.listen(0, () => {
http.get(server.address(), () => {})
})
t.teardown(() => server.close())
function handler (req, res) {
const serialized = serializers.reqSerializer(req)
t.equal(typeof serialized.id === 'function', false)
res.end()
}
})
test('req.id will be obtained from input request info.id when input request id does not exist', function (t) {
t.plan(1)
const server = http.createServer(handler)
server.unref()
server.listen(0, () => {
http.get(server.address(), () => {})
})
t.teardown(() => server.close())
function handler (req, res) {
req.info = { id: 'test' }
const serialized = serializers.reqSerializer(req)
t.equal(serialized.id, 'test')
res.end()
}
})
test('req.id has a non-function value with custom id function', function (t) {
t.plan(2)
const server = http.createServer(handler)
server.unref()
server.listen(0, () => {
http.get(server.address(), () => {})
})
t.teardown(() => server.close())
function handler (req, res) {
req.id = function () { return 42 }
const serialized = serializers.reqSerializer(req)
t.equal(typeof serialized.id === 'function', false)
t.equal(serialized.id, 42)
res.end()
}
})
test('req.url will be obtained from input request req.path when input request url is an object', function (t) {
t.plan(1)
const server = http.createServer(handler)
server.unref()
server.listen(0, () => {
http.get(server.address(), () => {})
})
t.teardown(() => server.close())
function handler (req, res) {
req.path = '/test'
const serialized = serializers.reqSerializer(req)
t.equal(serialized.url, '/test')
res.end()
}
})
test('req.url will be obtained from input request url.path when input request url is an object', function (t) {
t.plan(1)
const server = http.createServer(handler)
server.unref()
server.listen(0, () => {
http.get(server.address(), () => {})
})
t.teardown(() => server.close())
function handler (req, res) {
req.url = { path: '/test' }
const serialized = serializers.reqSerializer(req)
t.equal(serialized.url, '/test')
res.end()
}
})
test('req.url will be obtained from input request url when input request url is not an object', function (t) {
t.plan(1)
const server = http.createServer(handler)
server.unref()
server.listen(0, () => {
http.get(server.address(), () => {})
})
t.teardown(() => server.close())
function handler (req, res) {
req.url = '/test'
const serialized = serializers.reqSerializer(req)
t.equal(serialized.url, '/test')
res.end()
}
})
test('req.url will be empty when input request path and url are not defined', function (t) {
t.plan(1)
const server = http.createServer(handler)
server.unref()
server.listen(0, () => {
http.get(server.address(), () => {})
})
t.teardown(() => server.close())
function handler (req, res) {
const serialized = serializers.reqSerializer(req)
t.equal(serialized.url, '/')
res.end()
}
})
test('req.url will be obtained from input request originalUrl when available', function (t) {
t.plan(1)
const server = http.createServer(handler)
server.unref()
server.listen(0, () => {
http.get(server.address(), () => {})
})
t.teardown(() => server.close())
function handler (req, res) {
req.originalUrl = '/test'
const serialized = serializers.reqSerializer(req)
t.equal(serialized.url, '/test')
res.end()
}
})
test('req.url will be obtained from input request url when req path is a function', function (t) {
t.plan(1)
const server = http.createServer(handler)
server.unref()
server.listen(0, () => {
http.get(server.address(), () => {})
})
t.teardown(() => server.close())
function handler (req, res) {
req.path = function () {
throw new Error('unexpected invocation')
}
req.url = '/test'
const serialized = serializers.reqSerializer(req)
t.equal(serialized.url, '/test')
res.end()
}
})
test('req.url being undefined does not throw an error', function (t) {
t.plan(1)
const server = http.createServer(handler)
server.unref()
server.listen(0, () => {
http.get(server.address(), () => {})
})
t.teardown(() => server.close())
function handler (req, res) {
req.url = undefined
const serialized = serializers.reqSerializer(req)
t.equal(serialized.url, undefined)
res.end()
}
})
test('can wrap request serializers', function (t) {
t.plan(3)
const server = http.createServer(handler)
server.unref()
server.listen(0, () => {
http.get(server.address(), () => {})
})
t.teardown(() => server.close())
const serailizer = wrapRequestSerializer(function (req) {
t.ok(req.method)
t.equal(req.method, 'GET')
delete req.method
return req
})
function handler (req, res) {
const serialized = serailizer(req)
t.notOk(serialized.method)
res.end()
}
})
test('req.remoteAddress will be obtained from request socket.remoteAddress as fallback', function (t) {
t.plan(1)
const server = http.createServer(handler)
server.unref()
server.listen(0, () => {
http.get(server.address(), () => {})
})
t.teardown(() => server.close())
function handler (req, res) {
req.socket = { remoteAddress: 'http://localhost' }
const serialized = serializers.reqSerializer(req)
t.equal(serialized.remoteAddress, 'http://localhost')
res.end()
}
})
test('req.remoteAddress will be obtained from request info.remoteAddress if available', function (t) {
t.plan(1)
const server = http.createServer(handler)
server.unref()
server.listen(0, () => {
http.get(server.address(), () => {})
})
t.teardown(() => server.close())
function handler (req, res) {
req.info = { remoteAddress: 'http://localhost' }
const serialized = serializers.reqSerializer(req)
t.equal(serialized.remoteAddress, 'http://localhost')
res.end()
}
})
test('req.remotePort will be obtained from request socket.remotePort as fallback', function (t) {
t.plan(1)
const server = http.createServer(handler)
server.unref()
server.listen(0, () => {
http.get(server.address(), () => {})
})
t.teardown(() => server.close())
function handler (req, res) {
req.socket = { remotePort: 3000 }
const serialized = serializers.reqSerializer(req)
t.equal(serialized.remotePort, 3000)
res.end()
}
})
test('req.remotePort will be obtained from request info.remotePort if available', function (t) {
t.plan(1)
const server = http.createServer(handler)
server.unref()
server.listen(0, () => {
http.get(server.address(), () => {})
})
t.teardown(() => server.close())
function handler (req, res) {
req.info = { remotePort: 3000 }
const serialized = serializers.reqSerializer(req)
t.equal(serialized.remotePort, 3000)
res.end()
}
})
test('req.query is available', function (t) {
t.plan(1)
const server = http.createServer(handler)
server.unref()
server.listen(0, () => {
http.get(server.address(), () => {})
})
t.teardown(() => server.close())
function handler (req, res) {
req.query = '/foo?bar=foobar&bar=foo'
const serialized = serializers.reqSerializer(req)
t.equal(serialized.query, '/foo?bar=foobar&bar=foo')
res.end()
}
})
test('req.params is available', function (t) {
t.plan(1)
const server = http.createServer(handler)
server.unref()
server.listen(0, () => {
http.get(server.address(), () => {})
})
t.teardown(() => server.close())
function handler (req, res) {
req.params = '/foo/bar'
const serialized = serializers.reqSerializer(req)
t.equal(serialized.params, '/foo/bar')
res.end()
}
})
+109
View File
@@ -0,0 +1,109 @@
'use strict'
/* eslint-disable no-prototype-builtins */
const http = require('http')
const test = require('tap').test
const serializers = require('../lib/res')
const wrapResponseSerializer = require('../').wrapResponseSerializer
test('res.raw is not enumerable', function (t) {
t.plan(1)
const server = http.createServer(handler)
server.unref()
server.listen(0, () => {
http.get(server.address(), () => {})
})
t.teardown(() => server.close())
function handler (req, res) {
const serialized = serializers.resSerializer(res)
t.equal(serialized.propertyIsEnumerable('raw'), false)
res.end()
}
})
test('res.raw is available', function (t) {
t.plan(2)
const server = http.createServer(handler)
server.unref()
server.listen(0, () => {
http.get(server.address(), () => {})
})
t.teardown(() => server.close())
function handler (req, res) {
res.statusCode = 200
const serialized = serializers.resSerializer(res)
t.ok(serialized.raw)
t.equal(serialized.raw.statusCode, 200)
res.end()
}
})
test('can wrap response serializers', function (t) {
t.plan(3)
const server = http.createServer(handler)
server.unref()
server.listen(0, () => {
http.get(server.address(), () => {})
})
t.teardown(() => server.close())
const serializer = wrapResponseSerializer(function (res) {
t.ok(res.statusCode)
t.equal(res.statusCode, 200)
delete res.statusCode
return res
})
function handler (req, res) {
res.end()
res.statusCode = 200
const serialized = serializer(res)
t.notOk(serialized.statusCode)
}
})
test('res.headers is serialized', function (t) {
t.plan(1)
const server = http.createServer(handler)
server.unref()
server.listen(0, () => {
http.get(server.address(), () => {})
})
t.teardown(() => server.close())
function handler (req, res) {
res.setHeader('x-custom', 'y')
const serialized = serializers.resSerializer(res)
t.equal(serialized.headers['x-custom'], 'y')
res.end()
}
})
test('res.statusCode is null before headers are flushed', function (t) {
t.plan(1)
const server = http.createServer(handler)
server.unref()
server.listen(0, () => {
http.get(server.address(), () => {})
})
t.teardown(() => server.close())
function handler (req, res) {
const serialized = serializers.resSerializer(res)
t.equal(serialized.statusCode, null)
res.end()
}
})
+71
View File
@@ -0,0 +1,71 @@
import {IncomingMessage, ServerResponse} from "http";
import {
err,
errWithCause,
req,
res,
SerializedError,
SerializedRequest,
wrapErrorSerializer,
wrapRequestSerializer,
wrapResponseSerializer,
SerializedResponse
} from '../../';
const customErrorSerializer = (error: SerializedError) => {
return {
myOwnError: {
data: `${error.type}-${error.message}\n\n${error.stack}`,
}
};
};
const customRequestSerializer = (req: SerializedRequest) => {
const {
headers,
id,
method,
raw,
remoteAddress,
remotePort,
url,
query,
params,
} = req;
return {
myOwnRequest: {
data: `${method}-${id}-${remoteAddress}-${remotePort}-${url}`,
headers,
raw,
}
};
};
const customResponseSerializer = (res: SerializedResponse) => {
const {headers, raw, statusCode} = res;
return {
myOwnResponse: {
data: statusCode,
headers,
raw,
}
};
};
const fakeError = new Error('A fake error for testing');
const serializedError: SerializedError = err(fakeError);
const mySerializer = wrapErrorSerializer(customErrorSerializer);
const fakeErrorWithCause = new Error('A fake error for testing with cause', { cause: new Error('An inner fake error') });
const serializedErrorWithCause: SerializedError = errWithCause(fakeError);
const request: IncomingMessage = {} as IncomingMessage
const serializedRequest: SerializedRequest = req(request);
const myReqSerializer = wrapRequestSerializer(customRequestSerializer);
const response: ServerResponse = {} as ServerResponse
const myResSerializer = wrapResponseSerializer(customResponseSerializer);
const serializedResponse = res(response);
myResSerializer(response)