diff --git a/src/plugins/error/ThundraChaosError.ts b/src/plugins/error/ThundraChaosError.ts new file mode 100644 index 00000000..37d9b741 --- /dev/null +++ b/src/plugins/error/ThundraChaosError.ts @@ -0,0 +1,11 @@ +class ThundraChaosError extends Error { + constructor(message: string) { + super(); + this.message = message; + this.name = 'ThundraChaosError'; + Error.captureStackTrace(this, ThundraChaosError); + Object.setPrototypeOf(this, ThundraChaosError.prototype); + } +} + +export default ThundraChaosError; diff --git a/src/plugins/integrations/AWSIntegration.ts b/src/plugins/integrations/AWSIntegration.ts index 29742e6b..40475c69 100644 --- a/src/plugins/integrations/AWSIntegration.ts +++ b/src/plugins/integrations/AWSIntegration.ts @@ -15,6 +15,7 @@ import ThundraSpan from '../../opentracing/Span'; import * as opentracing from 'opentracing'; import LambdaEventUtils from '../utils/LambdaEventUtils'; import InvocationSupport from '../support/InvocationSupport'; +import ThundraChaosError from '../error/ThundraChaosError'; const shimmer = require('shimmer'); const Hook = require('require-in-the-middle'); @@ -566,25 +567,40 @@ class AWSIntegration implements Integration { request.on('error', (error: any) => { if (error && activeSpan) { activeSpan.setErrorTag(error); - activeSpan.close(); + if (error.injectedByThundra) { + activeSpan.close(); + } } }).on('complete', (response: any) => { if (response) { AWSIntegration.injectTraceLink(activeSpan, request, config); } if (activeSpan) { - activeSpan.close(); + try { + activeSpan.close(); + } catch (error) { + if (error instanceof ThundraChaosError) { + request.emit('error', error); + } else { + ThundraLogger.getInstance().error(error); + } + } } }); return originalFunction.apply(this, [originalCallback]); } } catch (error) { + if (error instanceof ThundraChaosError) { + this.response.error = error; + } else { + ThundraLogger.getInstance().error(error); + } + const originalFunction = integration.wrappedFuncs[wrappedFunctionName]; if (activeSpan) { activeSpan.close(); } - ThundraLogger.getInstance().error(error); return originalFunction.apply(this, [callback]); } }; diff --git a/src/plugins/listeners/ErrorInjectorSpanListener.ts b/src/plugins/listeners/ErrorInjectorSpanListener.ts index 33340fce..8ac533d3 100644 --- a/src/plugins/listeners/ErrorInjectorSpanListener.ts +++ b/src/plugins/listeners/ErrorInjectorSpanListener.ts @@ -1,5 +1,6 @@ import ThundraSpanListener from './ThundraSpanListener'; import ThundraSpan from '../../opentracing/Span'; +import ThundraChaosError from '../error/ThundraChaosError'; const koalas = require('koalas'); @@ -63,7 +64,7 @@ class ErrorInjectorSpanListener implements ThundraSpanListener { private _injectErrorWithCallback(span: ThundraSpan, me: any, callback: () => any): void { if (this.counter % this.injectCountFreq === 0) { - const error = new Error(this.errorMessage); + const error = new ThundraChaosError(this.errorMessage); error.name = this.errorType; span.setErrorTag(error); if (typeof(callback) === 'function') { @@ -76,7 +77,7 @@ class ErrorInjectorSpanListener implements ThundraSpanListener { private _injectError(span: ThundraSpan, me: any): void { if (this.counter % this.injectCountFreq === 0) { - const error = new Error(this.errorMessage); + const error = new ThundraChaosError(this.errorMessage); error.name = this.errorType; span.setErrorTag(error); this.counter++;