You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					148 lines
				
				3.7 KiB
			
		
		
			
		
	
	
					148 lines
				
				3.7 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								'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.is(serialized.type, 'Error')
							 | 
						||
| 
								 | 
							
								  t.is(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.is(serialized.type, 'Error')
							 | 
						||
| 
								 | 
							
								  t.is(serialized.message, 'foo')
							 | 
						||
| 
								 | 
							
								  t.ok(serialized.statusCode)
							 | 
						||
| 
								 | 
							
								  t.is(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.is(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.is(serialized.type, 'Error')
							 | 
						||
| 
								 | 
							
								  t.is(serialized.message, 'foo')
							 | 
						||
| 
								 | 
							
								  t.match(serialized.stack, /err\.test\.js:/)
							 | 
						||
| 
								 | 
							
								  t.is(serialized.inner.type, 'Error')
							 | 
						||
| 
								 | 
							
								  t.is(serialized.inner.message, 'bar')
							 | 
						||
| 
								 | 
							
								  t.match(serialized.inner.stack, /Error: bar/)
							 | 
						||
| 
								 | 
							
								  t.match(serialized.inner.stack, /err\.test\.js:/)
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								test('prevents infinite recursion', function (t) {
							 | 
						||
| 
								 | 
							
								  t.plan(4)
							 | 
						||
| 
								 | 
							
								  const err = Error('foo')
							 | 
						||
| 
								 | 
							
								  err.inner = err
							 | 
						||
| 
								 | 
							
								  const serialized = serializer(err)
							 | 
						||
| 
								 | 
							
								  t.is(serialized.type, 'Error')
							 | 
						||
| 
								 | 
							
								  t.is(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.is(serialized.type, 'Error')
							 | 
						||
| 
								 | 
							
								  t.is(serialized.message, 'foo')
							 | 
						||
| 
								 | 
							
								  t.match(serialized.stack, /err\.test\.js:/)
							 | 
						||
| 
								 | 
							
								  t.ok(serialized.inner)
							 | 
						||
| 
								 | 
							
								  t.is(serialized.inner.type, 'Error')
							 | 
						||
| 
								 | 
							
								  t.is(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.is(a.type, name)
							 | 
						||
| 
								 | 
							
								    t.is(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 is not an Error', function (t) {
							 | 
						||
| 
								 | 
							
								  t.plan(3)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  function check (a) {
							 | 
						||
| 
								 | 
							
								    t.is(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.is(serialized.type, 'Error')
							 | 
						||
| 
								 | 
							
								  t.is(serialized.message, 'foo')
							 | 
						||
| 
								 | 
							
								  t.match(serialized.stack, /err\.test\.js:/)
							 | 
						||
| 
								 | 
							
								  t.notOk(serialized.foo)
							 | 
						||
| 
								 | 
							
								  t.is(serialized.bar, 'bar')
							 | 
						||
| 
								 | 
							
								})
							 |