diff --git a/packages/opentelemetry-core/src/ExportResult.ts b/packages/opentelemetry-core/src/ExportResult.ts index bc73766e98..784ac9911d 100644 --- a/packages/opentelemetry-core/src/ExportResult.ts +++ b/packages/opentelemetry-core/src/ExportResult.ts @@ -14,8 +14,12 @@ * limitations under the License. */ -export enum ExportResult { +export interface ExportResult { + code: ExportResultCode; + error?: Error; +} + +export enum ExportResultCode { SUCCESS, - FAILED_NOT_RETRYABLE, - FAILED_RETRYABLE, + FAILED, } diff --git a/packages/opentelemetry-exporter-collector-proto/test/CollectorMetricExporter.test.ts b/packages/opentelemetry-exporter-collector-proto/test/CollectorMetricExporter.test.ts index ea7a25f1d8..621ba2d1b9 100644 --- a/packages/opentelemetry-exporter-collector-proto/test/CollectorMetricExporter.test.ts +++ b/packages/opentelemetry-exporter-collector-proto/test/CollectorMetricExporter.test.ts @@ -32,6 +32,7 @@ import { ensureExportedValueRecorderIsCorrect, } from './helper'; import { MetricRecord } from '@opentelemetry/metrics'; +import { ExportResult, ExportResultCode } from '@opentelemetry/core'; const fakeRequest = { end: function () {}, @@ -157,7 +158,6 @@ describe('CollectorMetricExporter - node with proto over http', () => { }); it('should log the successful message', done => { - const spyLoggerDebug = sinon.stub(collectorExporter.logger, 'debug'); const spyLoggerError = sinon.stub(collectorExporter.logger, 'error'); const responseSpy = sinon.spy(); @@ -168,25 +168,15 @@ describe('CollectorMetricExporter - node with proto over http', () => { const callback = args[1]; callback(mockRes); setTimeout(() => { - const response: any = spyLoggerDebug.args[1][0]; - assert.strictEqual(response, 'statusCode: 200'); + const result = responseSpy.args[0][0] as ExportResult; + assert.strictEqual(result.code, ExportResultCode.SUCCESS); assert.strictEqual(spyLoggerError.args.length, 0); - assert.strictEqual(responseSpy.args[0][0], 0); done(); }); }, waitTimeMS); }); it('should log the error message', done => { - const spyLoggerError = sinon.spy(); - const handler = core.loggingErrorHandler({ - debug: sinon.fake(), - info: sinon.fake(), - warn: sinon.fake(), - error: spyLoggerError, - }); - core.setGlobalErrorHandler(handler); - const responseSpy = sinon.spy(); collectorExporter.export(metrics, responseSpy); @@ -195,9 +185,10 @@ describe('CollectorMetricExporter - node with proto over http', () => { const callback = args[1]; callback(mockResError); setTimeout(() => { - const response = spyLoggerError.args[0][0] as string; - assert.ok(response.includes('"code":"400"')); - assert.strictEqual(responseSpy.args[0][0], 1); + const result = responseSpy.args[0][0] as ExportResult; + assert.strictEqual(result.code, ExportResultCode.FAILED); + // @ts-expect-error + assert.strictEqual(result.error?.code, 400); done(); }); }, waitTimeMS); diff --git a/packages/opentelemetry-exporter-collector-proto/test/CollectorTraceExporter.test.ts b/packages/opentelemetry-exporter-collector-proto/test/CollectorTraceExporter.test.ts index 6363bd4407..22e6d69586 100644 --- a/packages/opentelemetry-exporter-collector-proto/test/CollectorTraceExporter.test.ts +++ b/packages/opentelemetry-exporter-collector-proto/test/CollectorTraceExporter.test.ts @@ -29,6 +29,7 @@ import { ensureProtoSpanIsCorrect, mockedReadableSpan, } from './helper'; +import { ExportResult, ExportResultCode } from '@opentelemetry/core'; const fakeRequest = { end: function () {}, @@ -123,7 +124,6 @@ describe('CollectorTraceExporter - node with proto over http', () => { }); it('should log the successful message', done => { - const spyLoggerDebug = sinon.stub(collectorExporter.logger, 'debug'); const spyLoggerError = sinon.stub(collectorExporter.logger, 'error'); const responseSpy = sinon.spy(); @@ -134,25 +134,15 @@ describe('CollectorTraceExporter - node with proto over http', () => { const callback = args[1]; callback(mockRes); setTimeout(() => { - const response: any = spyLoggerDebug.args[1][0]; - assert.strictEqual(response, 'statusCode: 200'); + const result = responseSpy.args[0][0] as ExportResult; + assert.strictEqual(result.code, ExportResultCode.SUCCESS); assert.strictEqual(spyLoggerError.args.length, 0); - assert.strictEqual(responseSpy.args[0][0], 0); done(); }); }, waitTimeMS); }); it('should log the error message', done => { - const spyLoggerError = sinon.spy(); - const handler = core.loggingErrorHandler({ - debug: sinon.fake(), - info: sinon.fake(), - warn: sinon.fake(), - error: spyLoggerError, - }); - core.setGlobalErrorHandler(handler); - const responseSpy = sinon.spy(); collectorExporter.export(spans, responseSpy); @@ -161,10 +151,10 @@ describe('CollectorTraceExporter - node with proto over http', () => { const callback = args[1]; callback(mockResError); setTimeout(() => { - const response = spyLoggerError.args[0][0] as string; - - assert.ok(response.includes('"code":"400"')); - assert.strictEqual(responseSpy.args[0][0], 1); + const result = responseSpy.args[0][0] as ExportResult; + assert.strictEqual(result.code, ExportResultCode.FAILED); + // @ts-expect-error + assert.strictEqual(result.error.code, 400); done(); }); }, waitTimeMS); diff --git a/packages/opentelemetry-exporter-collector/src/CollectorExporterBase.ts b/packages/opentelemetry-exporter-collector/src/CollectorExporterBase.ts index 2b3ed5b066..4b2775abb7 100644 --- a/packages/opentelemetry-exporter-collector/src/CollectorExporterBase.ts +++ b/packages/opentelemetry-exporter-collector/src/CollectorExporterBase.ts @@ -17,8 +17,8 @@ import { Attributes, Logger } from '@opentelemetry/api'; import { ExportResult, + ExportResultCode, NoopLogger, - globalErrorHandler, } from '@opentelemetry/core'; import { CollectorExporterError, @@ -70,21 +70,19 @@ export abstract class CollectorExporterBase< */ export(items: ExportItem[], resultCallback: (result: ExportResult) => void) { if (this._isShutdown) { - resultCallback(ExportResult.FAILED_NOT_RETRYABLE); + resultCallback({ + code: ExportResultCode.FAILED, + error: new Error('Exporter has been shutdown'), + }); return; } this._export(items) .then(() => { - resultCallback(ExportResult.SUCCESS); + resultCallback({ code: ExportResultCode.SUCCESS }); }) .catch((error: ExportServiceError) => { - globalErrorHandler(error); - if (error.code && error.code < 500) { - resultCallback(ExportResult.FAILED_NOT_RETRYABLE); - } else { - resultCallback(ExportResult.FAILED_RETRYABLE); - } + resultCallback({ code: ExportResultCode.FAILED, error }); }); } diff --git a/packages/opentelemetry-exporter-collector/src/platform/browser/util.ts b/packages/opentelemetry-exporter-collector/src/platform/browser/util.ts index 03a4c9badd..5b79b77061 100644 --- a/packages/opentelemetry-exporter-collector/src/platform/browser/util.ts +++ b/packages/opentelemetry-exporter-collector/src/platform/browser/util.ts @@ -72,7 +72,7 @@ export function sendWithXhr( onSuccess(); } else { const error = new collectorTypes.CollectorExporterError( - xhr.responseText, + `Failed to export with XHR (status: ${xhr.status})`, xhr.status ); diff --git a/packages/opentelemetry-exporter-collector/test/browser/CollectorMetricExporter.test.ts b/packages/opentelemetry-exporter-collector/test/browser/CollectorMetricExporter.test.ts index e3a7e3c9e2..252e3cd49c 100644 --- a/packages/opentelemetry-exporter-collector/test/browser/CollectorMetricExporter.test.ts +++ b/packages/opentelemetry-exporter-collector/test/browser/CollectorMetricExporter.test.ts @@ -14,11 +14,7 @@ * limitations under the License. */ -import { - NoopLogger, - setGlobalErrorHandler, - loggingErrorHandler, -} from '@opentelemetry/core'; +import { ExportResultCode, NoopLogger } from '@opentelemetry/core'; import * as assert from 'assert'; import * as sinon from 'sinon'; import { CollectorMetricExporter } from '../../src/platform/browser/index'; @@ -166,25 +162,12 @@ describe('CollectorMetricExporter - web', () => { }); it('should log the error message', done => { - const spyLoggerError = sinon.spy(); - const handler = loggingErrorHandler({ - debug: sinon.fake(), - info: sinon.fake(), - warn: sinon.fake(), - error: spyLoggerError, - }); - setGlobalErrorHandler(handler); - const spyLoggerDebug = sinon.stub(collectorExporter.logger, 'debug'); spyBeacon.restore(); spyBeacon = sinon.stub(window.navigator, 'sendBeacon').returns(false); - collectorExporter.export(metrics, () => {}); - - setTimeout(() => { - const response: any = spyLoggerError.args[0][0] as string; - assert.ok(response.includes('sendBeacon - cannot send')); - assert.strictEqual(spyLoggerDebug.args.length, 1); - + collectorExporter.export(metrics, result => { + assert.deepStrictEqual(result.code, ExportResultCode.FAILED); + assert.ok(result.error?.message.includes('cannot send')); done(); }); }); @@ -290,19 +273,9 @@ describe('CollectorMetricExporter - web', () => { }); it('should log the error message', done => { - const spyLoggerError = sinon.spy(); - const handler = loggingErrorHandler({ - debug: sinon.fake(), - info: sinon.fake(), - warn: sinon.fake(), - error: spyLoggerError, - }); - setGlobalErrorHandler(handler); - - collectorExporter.export(metrics, () => { - const response = spyLoggerError.args[0][0] as string; - assert.ok(response.includes('"code":"400"')); - + collectorExporter.export(metrics, result => { + assert.deepStrictEqual(result.code, ExportResultCode.FAILED); + assert.ok(result.error?.message.includes('Failed to export')); assert.strictEqual(spyBeacon.callCount, 0); done(); }); diff --git a/packages/opentelemetry-exporter-collector/test/browser/CollectorTraceExporter.test.ts b/packages/opentelemetry-exporter-collector/test/browser/CollectorTraceExporter.test.ts index 25e795f911..776a01c04b 100644 --- a/packages/opentelemetry-exporter-collector/test/browser/CollectorTraceExporter.test.ts +++ b/packages/opentelemetry-exporter-collector/test/browser/CollectorTraceExporter.test.ts @@ -14,11 +14,7 @@ * limitations under the License. */ -import { - NoopLogger, - setGlobalErrorHandler, - loggingErrorHandler, -} from '@opentelemetry/core'; +import { NoopLogger, ExportResultCode } from '@opentelemetry/core'; import { ReadableSpan } from '@opentelemetry/tracing'; import * as assert from 'assert'; import * as sinon from 'sinon'; @@ -135,29 +131,12 @@ describe('CollectorTraceExporter - web', () => { }); it('should log the error message', done => { - const spyLoggerError = sinon.spy(); - const handler = loggingErrorHandler({ - debug: sinon.fake(), - info: sinon.fake(), - warn: sinon.fake(), - error: spyLoggerError, - }); - setGlobalErrorHandler(handler); - - const spyLoggerDebug = sinon.stub( - collectorTraceExporter.logger, - 'debug' - ); spyBeacon.restore(); spyBeacon = sinon.stub(window.navigator, 'sendBeacon').returns(false); - collectorTraceExporter.export(spans, () => {}); - - setTimeout(() => { - const response = spyLoggerError.args[0][0] as string; - assert.ok(response.includes('sendBeacon - cannot send')); - assert.strictEqual(spyLoggerDebug.args.length, 1); - + collectorTraceExporter.export(spans, result => { + assert.deepStrictEqual(result.code, ExportResultCode.FAILED); + assert.ok(result.error?.message.includes('cannot send')); done(); }); }); @@ -236,21 +215,9 @@ describe('CollectorTraceExporter - web', () => { }); it('should log the error message', done => { - const spyLoggerError = sinon.spy(); - const handler = loggingErrorHandler({ - debug: sinon.fake(), - info: sinon.fake(), - warn: sinon.fake(), - error: spyLoggerError, - }); - setGlobalErrorHandler(handler); - - collectorTraceExporter.export(spans, () => { - const response = spyLoggerError.args[0][0] as string; - - assert.ok(response.includes('"code":"400"')); - - assert.strictEqual(spyBeacon.callCount, 0); + collectorTraceExporter.export(spans, result => { + assert.deepStrictEqual(result.code, ExportResultCode.FAILED); + assert.ok(result.error?.message.includes('Failed to export')); done(); }); diff --git a/packages/opentelemetry-exporter-collector/test/common/CollectorMetricExporter.test.ts b/packages/opentelemetry-exporter-collector/test/common/CollectorMetricExporter.test.ts index 08d27dc826..2766c0c5f5 100644 --- a/packages/opentelemetry-exporter-collector/test/common/CollectorMetricExporter.test.ts +++ b/packages/opentelemetry-exporter-collector/test/common/CollectorMetricExporter.test.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { ExportResult, NoopLogger } from '@opentelemetry/core'; +import { ExportResultCode, NoopLogger } from '@opentelemetry/core'; import * as assert from 'assert'; import * as sinon from 'sinon'; import { CollectorExporterBase } from '../../src/CollectorExporterBase'; @@ -149,8 +149,8 @@ describe('CollectorMetricExporter - common', () => { collectorExporter.export(metrics, callbackSpy); const returnCode = callbackSpy.args[0][0]; assert.strictEqual( - returnCode, - ExportResult.FAILED_NOT_RETRYABLE, + returnCode.code, + ExportResultCode.FAILED, 'return value is wrong' ); assert.strictEqual(spySend.callCount, 0, 'should not call send'); @@ -158,12 +158,12 @@ describe('CollectorMetricExporter - common', () => { ); }); describe('when an error occurs', () => { - it('should return a Not Retryable Error', done => { + it('should return failed export result', done => { spySend.throws({ - code: 100, + code: 600, details: 'Test error', metadata: {}, - message: 'Non-retryable', + message: 'Non-Retryable', stack: 'Stack', }); const callbackSpy = sinon.spy(); @@ -171,31 +171,14 @@ describe('CollectorMetricExporter - common', () => { setTimeout(() => { const returnCode = callbackSpy.args[0][0]; assert.strictEqual( - returnCode, - ExportResult.FAILED_NOT_RETRYABLE, + returnCode.code, + ExportResultCode.FAILED, 'return value is wrong' ); - assert.strictEqual(spySend.callCount, 1, 'should call send'); - done(); - }); - }); - - it('should return a Retryable Error', done => { - spySend.throws({ - code: 600, - details: 'Test error', - metadata: {}, - message: 'Retryable', - stack: 'Stack', - }); - const callbackSpy = sinon.spy(); - collectorExporter.export(metrics, callbackSpy); - setTimeout(() => { - const returnCode = callbackSpy.args[0][0]; assert.strictEqual( - returnCode, - ExportResult.FAILED_RETRYABLE, - 'return value is wrong' + returnCode.error.message, + 'Non-Retryable', + 'return error message is wrong' ); assert.strictEqual(spySend.callCount, 1, 'should call send'); done(); diff --git a/packages/opentelemetry-exporter-collector/test/common/CollectorTraceExporter.test.ts b/packages/opentelemetry-exporter-collector/test/common/CollectorTraceExporter.test.ts index c6f1fad302..03aedf7ca4 100644 --- a/packages/opentelemetry-exporter-collector/test/common/CollectorTraceExporter.test.ts +++ b/packages/opentelemetry-exporter-collector/test/common/CollectorTraceExporter.test.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { ExportResult, NoopLogger } from '@opentelemetry/core'; +import { ExportResultCode, NoopLogger } from '@opentelemetry/core'; import { ReadableSpan } from '@opentelemetry/tracing'; import * as assert from 'assert'; import * as sinon from 'sinon'; @@ -148,8 +148,8 @@ describe('CollectorTraceExporter - common', () => { const returnCode = callbackSpy.args[0][0]; assert.strictEqual( - returnCode, - ExportResult.FAILED_NOT_RETRYABLE, + returnCode.code, + ExportResultCode.FAILED, 'return value is wrong' ); assert.strictEqual(spySend.callCount, 0, 'should not call send'); @@ -157,7 +157,7 @@ describe('CollectorTraceExporter - common', () => { ); }); describe('when an error occurs', () => { - it('should return a Not Retryable Error', done => { + it('should return failed export result', done => { const spans: ReadableSpan[] = []; spans.push(Object.assign({}, mockedReadableSpan)); spySend.throws({ @@ -172,33 +172,14 @@ describe('CollectorTraceExporter - common', () => { setTimeout(() => { const returnCode = callbackSpy.args[0][0]; assert.strictEqual( - returnCode, - ExportResult.FAILED_NOT_RETRYABLE, + returnCode.code, + ExportResultCode.FAILED, 'return value is wrong' ); - assert.strictEqual(spySend.callCount, 1, 'should call send'); - done(); - }); - }); - - it('should return a Retryable Error', done => { - const spans: ReadableSpan[] = []; - spans.push(Object.assign({}, mockedReadableSpan)); - spySend.throws({ - code: 600, - details: 'Test error', - metadata: {}, - message: 'Retryable', - stack: 'Stack', - }); - const callbackSpy = sinon.spy(); - collectorExporter.export(spans, callbackSpy); - setTimeout(() => { - const returnCode = callbackSpy.args[0][0]; assert.strictEqual( - returnCode, - ExportResult.FAILED_RETRYABLE, - 'return value is wrong' + returnCode.error.message, + 'Non-retryable', + 'return error message is wrong' ); assert.strictEqual(spySend.callCount, 1, 'should call send'); done(); diff --git a/packages/opentelemetry-exporter-collector/test/node/CollectorMetricExporter.test.ts b/packages/opentelemetry-exporter-collector/test/node/CollectorMetricExporter.test.ts index 85f447cbab..14d9314c79 100644 --- a/packages/opentelemetry-exporter-collector/test/node/CollectorMetricExporter.test.ts +++ b/packages/opentelemetry-exporter-collector/test/node/CollectorMetricExporter.test.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { ConsoleLogger, LogLevel } from '@opentelemetry/core'; +import { ConsoleLogger, ExportResultCode, LogLevel } from '@opentelemetry/core'; import * as core from '@opentelemetry/core'; import * as http from 'http'; import * as assert from 'assert'; @@ -44,10 +44,6 @@ const mockRes = { statusCode: 200, }; -const mockResError = { - statusCode: 400, -}; - const address = 'localhost:1501'; describe('CollectorMetricExporter - node with json over http', () => { @@ -185,33 +181,10 @@ describe('CollectorMetricExporter - node with json over http', () => { const response: any = spyLoggerDebug.args[1][0]; assert.strictEqual(response, 'statusCode: 200'); assert.strictEqual(spyLoggerError.args.length, 0); - assert.strictEqual(responseSpy.args[0][0], 0); - done(); - }); - }); - }); - - it('should log the error message', done => { - const spyLoggerError = sinon.spy(); - const handler = core.loggingErrorHandler({ - debug: sinon.fake(), - info: sinon.fake(), - warn: sinon.fake(), - error: spyLoggerError, - }); - core.setGlobalErrorHandler(handler); - - const responseSpy = sinon.spy(); - collectorExporter.export(metrics, responseSpy); - - setTimeout(() => { - const args = spyRequest.args[0]; - const callback = args[1]; - callback(mockResError); - setTimeout(() => { - const response = spyLoggerError.args[0][0] as string; - assert.ok(response.includes('"code":"400"')); - assert.strictEqual(responseSpy.args[0][0], 1); + assert.strictEqual( + responseSpy.args[0][0].code, + ExportResultCode.SUCCESS + ); done(); }); }); diff --git a/packages/opentelemetry-exporter-collector/test/node/CollectorTraceExporter.test.ts b/packages/opentelemetry-exporter-collector/test/node/CollectorTraceExporter.test.ts index 0429cb57f1..aa9076a896 100644 --- a/packages/opentelemetry-exporter-collector/test/node/CollectorTraceExporter.test.ts +++ b/packages/opentelemetry-exporter-collector/test/node/CollectorTraceExporter.test.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { ConsoleLogger, LogLevel } from '@opentelemetry/core'; +import { ConsoleLogger, ExportResultCode, LogLevel } from '@opentelemetry/core'; import * as core from '@opentelemetry/core'; import { ReadableSpan } from '@opentelemetry/tracing'; import * as http from 'http'; @@ -40,9 +40,6 @@ const mockRes = { statusCode: 200, }; -const mockResError = { - statusCode: 400, -}; const address = 'localhost:1501'; describe('CollectorTraceExporter - node with json over http', () => { @@ -151,34 +148,10 @@ describe('CollectorTraceExporter - node with json over http', () => { const response: any = spyLoggerDebug.args[1][0]; assert.strictEqual(response, 'statusCode: 200'); assert.strictEqual(spyLoggerError.args.length, 0); - assert.strictEqual(responseSpy.args[0][0], 0); - done(); - }); - }); - }); - - it('should log the error message', done => { - const spyLoggerError = sinon.spy(); - const handler = core.loggingErrorHandler({ - debug: sinon.fake(), - info: sinon.fake(), - warn: sinon.fake(), - error: spyLoggerError, - }); - core.setGlobalErrorHandler(handler); - - const responseSpy = sinon.spy(); - collectorExporter.export(spans, responseSpy); - - setTimeout(() => { - const args = spyRequest.args[0]; - const callback = args[1]; - callback(mockResError); - setTimeout(() => { - const response = spyLoggerError.args[0][0] as string; - - assert.ok(response.includes('"code":"400"')); - assert.strictEqual(responseSpy.args[0][0], 1); + assert.strictEqual( + responseSpy.args[0][0].code, + ExportResultCode.SUCCESS + ); done(); }); }); diff --git a/packages/opentelemetry-exporter-jaeger/src/jaeger.ts b/packages/opentelemetry-exporter-jaeger/src/jaeger.ts index 0078b26644..f9bac2207a 100644 --- a/packages/opentelemetry-exporter-jaeger/src/jaeger.ts +++ b/packages/opentelemetry-exporter-jaeger/src/jaeger.ts @@ -17,8 +17,8 @@ import * as api from '@opentelemetry/api'; import { ExportResult, + ExportResultCode, NoopLogger, - globalErrorHandler, } from '@opentelemetry/core'; import { ReadableSpan, SpanExporter } from '@opentelemetry/tracing'; import { Socket } from 'dgram'; @@ -81,11 +81,11 @@ export class JaegerExporter implements SpanExporter { resultCallback: (result: ExportResult) => void ): void { if (spans.length === 0) { - return resultCallback(ExportResult.SUCCESS); + return resultCallback({ code: ExportResultCode.SUCCESS }); } this._logger.debug('Jaeger exporter export'); - this._sendSpans(spans, resultCallback).catch(err => { - globalErrorHandler(err); + this._sendSpans(spans, resultCallback).catch(error => { + return resultCallback({ code: ExportResultCode.FAILED, error }); }); } @@ -135,10 +135,9 @@ export class JaegerExporter implements SpanExporter { for (const span of thriftSpan) { try { await this._append(span); - } catch (err) { - globalErrorHandler(err); + } catch (error) { // TODO right now we break out on first error, is that desirable? - if (done) return done(ExportResult.FAILED_NOT_RETRYABLE); + if (done) return done({ code: ExportResultCode.FAILED, error }); } } this._logger.debug('successful append for : %s', thriftSpan.length); @@ -146,7 +145,7 @@ export class JaegerExporter implements SpanExporter { // Flush all spans on each export. No-op if span buffer is empty await this._flush(); - if (done) return done(ExportResult.SUCCESS); + if (done) return done({ code: ExportResultCode.SUCCESS }); } private async _append(span: jaegerTypes.ThriftSpan): Promise { diff --git a/packages/opentelemetry-exporter-jaeger/test/jaeger.test.ts b/packages/opentelemetry-exporter-jaeger/test/jaeger.test.ts index b74b1cd2d4..c6eec8759c 100644 --- a/packages/opentelemetry-exporter-jaeger/test/jaeger.test.ts +++ b/packages/opentelemetry-exporter-jaeger/test/jaeger.test.ts @@ -15,13 +15,11 @@ */ import * as assert from 'assert'; -import * as sinon from 'sinon'; import { JaegerExporter } from '../src'; import { ExportResult, - loggingErrorHandler, + ExportResultCode, NoopLogger, - setGlobalErrorHandler, } from '@opentelemetry/core'; import * as api from '@opentelemetry/api'; import { ThriftProcess } from '../src/types'; @@ -151,13 +149,13 @@ describe('JaegerExporter', () => { it('should skip send with empty list', () => { exporter.export([], (result: ExportResult) => { - assert.strictEqual(result, ExportResult.SUCCESS); + assert.strictEqual(result.code, ExportResultCode.SUCCESS); }); }); it('should send spans to Jaeger backend and return with Success', () => { exporter.export([readableSpan], (result: ExportResult) => { - assert.strictEqual(result, ExportResult.SUCCESS); + assert.strictEqual(result.code, ExportResultCode.SUCCESS); }); }); @@ -181,10 +179,8 @@ describe('JaegerExporter', () => { exporter.export([readableSpan], () => {}); }); - it('should call globalErrorHandler on error', () => { + it('should return failed export result on error', () => { nock.cleanAll(); - const errorHandlerSpy = sinon.spy(); - setGlobalErrorHandler(errorHandlerSpy); const expectedError = new Error('whoops'); const mockedEndpoint = 'http://testendpoint'; const scope = nock(mockedEndpoint) @@ -195,16 +191,11 @@ describe('JaegerExporter', () => { endpoint: mockedEndpoint, }); - exporter.export([readableSpan], () => { + exporter.export([readableSpan], result => { scope.done(); - assert.strictEqual(errorHandlerSpy.callCount, 1); - - const [[error]] = errorHandlerSpy.args; - assert.strictEqual(error, expectedError); + assert.strictEqual(result.code, ExportResultCode.FAILED); + assert.ok(result.error?.message.includes(expectedError.message)); }); - - // reset global error handler - setGlobalErrorHandler(loggingErrorHandler()); }); }); }); diff --git a/packages/opentelemetry-exporter-prometheus/src/PrometheusExporter.ts b/packages/opentelemetry-exporter-prometheus/src/PrometheusExporter.ts index 42d658c256..c83fcb944b 100644 --- a/packages/opentelemetry-exporter-prometheus/src/PrometheusExporter.ts +++ b/packages/opentelemetry-exporter-prometheus/src/PrometheusExporter.ts @@ -19,6 +19,7 @@ import { ExportResult, NoopLogger, globalErrorHandler, + ExportResultCode, } from '@opentelemetry/core'; import { MetricExporter, MetricRecord } from '@opentelemetry/metrics'; import { createServer, IncomingMessage, Server, ServerResponse } from 'http'; @@ -86,7 +87,7 @@ export class PrometheusExporter implements MetricExporter { if (!this._server) { // It is conceivable that the _server may not be started as it is an async startup // However unlikely, if this happens the caller may retry the export - cb(ExportResult.FAILED_RETRYABLE); + cb({ code: ExportResultCode.FAILED }); return; } @@ -96,7 +97,7 @@ export class PrometheusExporter implements MetricExporter { this._batcher.process(record); } - cb(ExportResult.SUCCESS); + cb({ code: ExportResultCode.SUCCESS }); } /** diff --git a/packages/opentelemetry-exporter-zipkin/src/platform/browser/util.ts b/packages/opentelemetry-exporter-zipkin/src/platform/browser/util.ts index b72df3d665..a10bfa919c 100644 --- a/packages/opentelemetry-exporter-zipkin/src/platform/browser/util.ts +++ b/packages/opentelemetry-exporter-zipkin/src/platform/browser/util.ts @@ -15,7 +15,11 @@ */ import * as api from '@opentelemetry/api'; -import { ExportResult, globalErrorHandler } from '@opentelemetry/core'; +import { + ExportResult, + ExportResultCode, + globalErrorHandler, +} from '@opentelemetry/core'; import * as zipkinTypes from '../../types'; /** @@ -45,7 +49,7 @@ export function prepareSend( ) { if (zipkinSpans.length === 0) { logger.debug('Zipkin send with empty spans'); - return done(ExportResult.SUCCESS); + return done({ code: ExportResultCode.SUCCESS }); } const payload = JSON.stringify(zipkinSpans); if (useBeacon) { @@ -71,10 +75,12 @@ function sendWithBeacon( ) { if (navigator.sendBeacon(urlStr, data)) { logger.debug('sendBeacon - can send', data); - done(ExportResult.SUCCESS); + done({ code: ExportResultCode.SUCCESS }); } else { - globalErrorHandler(new Error(`sendBeacon - cannot send ${data}`)); - done(ExportResult.FAILED_NOT_RETRYABLE); + done({ + code: ExportResultCode.FAILED, + error: new Error(`sendBeacon - cannot send ${data}`), + }); } } @@ -109,18 +115,21 @@ function sendWithXhr( ); if (xhr.status >= 200 && xhr.status < 400) { - return done(ExportResult.SUCCESS); - } else if (statusCode < 500) { - return done(ExportResult.FAILED_NOT_RETRYABLE); + return done({ code: ExportResultCode.SUCCESS }); } else { - return done(ExportResult.FAILED_RETRYABLE); + return done({ + code: ExportResultCode.FAILED, + error: new Error( + `Got unexpected status code from zipkin: ${xhr.status}` + ), + }); } } }; xhr.onerror = msg => { globalErrorHandler(new Error(`Zipkin request error: ${msg}`)); - return done(ExportResult.FAILED_RETRYABLE); + return done({ code: ExportResultCode.FAILED }); }; // Issue request to remote service diff --git a/packages/opentelemetry-exporter-zipkin/src/platform/node/util.ts b/packages/opentelemetry-exporter-zipkin/src/platform/node/util.ts index 9686f73a40..7cafd85929 100644 --- a/packages/opentelemetry-exporter-zipkin/src/platform/node/util.ts +++ b/packages/opentelemetry-exporter-zipkin/src/platform/node/util.ts @@ -15,7 +15,7 @@ */ import * as api from '@opentelemetry/api'; -import { ExportResult, globalErrorHandler } from '@opentelemetry/core'; +import { ExportResult, ExportResultCode } from '@opentelemetry/core'; import * as http from 'http'; import * as https from 'https'; import * as url from 'url'; @@ -51,7 +51,7 @@ export function prepareSend( ) { if (zipkinSpans.length === 0) { logger.debug('Zipkin send with empty spans'); - return done(ExportResult.SUCCESS); + return done({ code: ExportResultCode.SUCCESS }); } const { request } = reqOpts.protocol === 'http:' ? http : https; @@ -70,20 +70,24 @@ export function prepareSend( // Consider 2xx and 3xx as success. if (statusCode < 400) { - return done(ExportResult.SUCCESS); + return done({ code: ExportResultCode.SUCCESS }); // Consider 4xx as failed non-retriable. - } else if (statusCode < 500) { - return done(ExportResult.FAILED_NOT_RETRYABLE); - // Consider 5xx as failed retriable. } else { - return done(ExportResult.FAILED_RETRYABLE); + return done({ + code: ExportResultCode.FAILED, + error: new Error( + `Got unexpected status code from zipkin: ${statusCode}` + ), + }); } }); }); - req.on('error', (err: Error) => { - globalErrorHandler(err); - return done(ExportResult.FAILED_RETRYABLE); + req.on('error', error => { + return done({ + code: ExportResultCode.FAILED, + error, + }); }); // Issue request to remote service diff --git a/packages/opentelemetry-exporter-zipkin/src/zipkin.ts b/packages/opentelemetry-exporter-zipkin/src/zipkin.ts index bb1083bb23..cceb8d7d19 100644 --- a/packages/opentelemetry-exporter-zipkin/src/zipkin.ts +++ b/packages/opentelemetry-exporter-zipkin/src/zipkin.ts @@ -15,7 +15,11 @@ */ import * as api from '@opentelemetry/api'; -import { ExportResult, NoopLogger } from '@opentelemetry/core'; +import { + ExportResult, + ExportResultCode, + NoopLogger, +} from '@opentelemetry/core'; import { SpanExporter, ReadableSpan } from '@opentelemetry/tracing'; import { prepareSend } from './platform/index'; import * as zipkinTypes from './types'; @@ -66,7 +70,12 @@ export class ZipkinExporter implements SpanExporter { } this._logger.debug('Zipkin exporter export'); if (this._isShutdown) { - setTimeout(() => resultCallback(ExportResult.FAILED_NOT_RETRYABLE)); + setTimeout(() => + resultCallback({ + code: ExportResultCode.FAILED, + error: new Error('Exporter has been shutdown'), + }) + ); return; } const promise = new Promise(resolve => { diff --git a/packages/opentelemetry-exporter-zipkin/test/node/zipkin.test.ts b/packages/opentelemetry-exporter-zipkin/test/node/zipkin.test.ts index 298cd04f26..18e8b3fd25 100644 --- a/packages/opentelemetry-exporter-zipkin/test/node/zipkin.test.ts +++ b/packages/opentelemetry-exporter-zipkin/test/node/zipkin.test.ts @@ -16,14 +16,12 @@ import * as assert from 'assert'; import * as nock from 'nock'; -import * as sinon from 'sinon'; import { ReadableSpan } from '@opentelemetry/tracing'; import { ExportResult, NoopLogger, hrTimeToMicroseconds, - setGlobalErrorHandler, - loggingErrorHandler, + ExportResultCode, } from '@opentelemetry/core'; import * as api from '@opentelemetry/api'; import { Resource } from '@opentelemetry/resources'; @@ -118,7 +116,7 @@ describe('Zipkin Exporter - node', () => { }); exporter.export([], (result: ExportResult) => { - assert.strictEqual(result, ExportResult.SUCCESS); + assert.strictEqual(result.code, ExportResultCode.SUCCESS); }); }); @@ -195,7 +193,7 @@ describe('Zipkin Exporter - node', () => { exporter.export([span1, span2], (result: ExportResult) => { scope.done(); - assert.strictEqual(result, ExportResult.SUCCESS); + assert.strictEqual(result.code, ExportResultCode.SUCCESS); assert.deepStrictEqual(requestBody, [ // Span 1 { @@ -252,11 +250,11 @@ describe('Zipkin Exporter - node', () => { exporter.export([getReadableSpan()], (result: ExportResult) => { scope.done(); - assert.strictEqual(result, ExportResult.SUCCESS); + assert.strictEqual(result.code, ExportResultCode.SUCCESS); }); }); - it('should return FailedNonRetryable with 4xx', () => { + it('should return Failed result with 4xx', () => { const scope = nock('http://localhost:9411') .post('/api/v2/spans') .reply(400); @@ -268,11 +266,11 @@ describe('Zipkin Exporter - node', () => { exporter.export([getReadableSpan()], (result: ExportResult) => { scope.done(); - assert.strictEqual(result, ExportResult.FAILED_NOT_RETRYABLE); + assert.strictEqual(result.code, ExportResultCode.FAILED); }); }); - it('should return FailedRetryable with 5xx', () => { + it('should return failed result with 5xx', () => { const scope = nock('http://localhost:9411') .post('/api/v2/spans') .reply(500); @@ -284,11 +282,11 @@ describe('Zipkin Exporter - node', () => { exporter.export([getReadableSpan()], (result: ExportResult) => { scope.done(); - assert.strictEqual(result, ExportResult.FAILED_RETRYABLE); + assert.strictEqual(result.code, ExportResultCode.FAILED); }); }); - it('should return FailedRetryable with socket error', () => { + it('should return failed result with socket error', () => { const scope = nock('http://localhost:9411') .post('/api/v2/spans') .replyWithError(new Error('My Socket Error')); @@ -300,11 +298,11 @@ describe('Zipkin Exporter - node', () => { exporter.export([getReadableSpan()], (result: ExportResult) => { scope.done(); - assert.strictEqual(result, ExportResult.FAILED_RETRYABLE); + assert.strictEqual(result.code, ExportResultCode.FAILED); }); }); - it('should return FailedNonRetryable after shutdown', done => { + it('should return failed result after shutdown', done => { const exporter = new ZipkinExporter({ serviceName: 'my-service', logger: new NoopLogger(), @@ -313,7 +311,7 @@ describe('Zipkin Exporter - node', () => { exporter.shutdown(); exporter.export([getReadableSpan()], (result: ExportResult) => { - assert.strictEqual(result, ExportResult.FAILED_NOT_RETRYABLE); + assert.strictEqual(result.code, ExportResultCode.FAILED); done(); }); }); @@ -468,8 +466,6 @@ describe('Zipkin Exporter - node', () => { }); it('should call globalErrorHandler on error', () => { - const errorHandlerSpy = sinon.spy(); - setGlobalErrorHandler(errorHandlerSpy); const expectedError = new Error('Whoops'); const scope = nock('http://localhost:9411') .post('/api/v2/spans') @@ -481,14 +477,10 @@ describe('Zipkin Exporter - node', () => { }); exporter.export([getReadableSpan()], (result: ExportResult) => { + assert.deepStrictEqual(result.code, ExportResultCode.FAILED); + assert.deepStrictEqual(result.error, expectedError); scope.done(); }); - - const [[error]] = errorHandlerSpy.args; - - assert.strictEqual(errorHandlerSpy.callCount, 1); - assert.strictEqual(error, expectedError); - setGlobalErrorHandler(loggingErrorHandler()); }); }); }); diff --git a/packages/opentelemetry-metrics/src/export/ConsoleMetricExporter.ts b/packages/opentelemetry-metrics/src/export/ConsoleMetricExporter.ts index 0b4977e98d..9ac04fd3d0 100644 --- a/packages/opentelemetry-metrics/src/export/ConsoleMetricExporter.ts +++ b/packages/opentelemetry-metrics/src/export/ConsoleMetricExporter.ts @@ -15,7 +15,7 @@ */ import { MetricExporter, MetricRecord, Histogram } from './types'; -import { ExportResult } from '@opentelemetry/core'; +import { ExportResult, ExportResultCode } from '@opentelemetry/core'; /** * This is implementation of {@link MetricExporter} that prints metrics data to @@ -41,7 +41,7 @@ export class ConsoleMetricExporter implements MetricExporter { console.log(point.value); } } - return resultCallback(ExportResult.SUCCESS); + return resultCallback({ code: ExportResultCode.SUCCESS }); } shutdown(): Promise { diff --git a/packages/opentelemetry-metrics/src/export/Controller.ts b/packages/opentelemetry-metrics/src/export/Controller.ts index d160fa7304..c1f698edf5 100644 --- a/packages/opentelemetry-metrics/src/export/Controller.ts +++ b/packages/opentelemetry-metrics/src/export/Controller.ts @@ -15,7 +15,7 @@ */ import { - ExportResult, + ExportResultCode, unrefTimer, globalErrorHandler, } from '@opentelemetry/core'; @@ -53,9 +53,10 @@ export class PushController extends Controller { this._exporter.export( this._meter.getBatcher().checkPointSet(), result => { - if (result !== ExportResult.SUCCESS) { + if (result.code !== ExportResultCode.SUCCESS) { globalErrorHandler( - new Error('PushController: export failed in _collect') + result.error ?? + new Error('PushController: export failed in _collect') ); } resolve(); diff --git a/packages/opentelemetry-metrics/test/export/Controller.test.ts b/packages/opentelemetry-metrics/test/export/Controller.test.ts new file mode 100644 index 0000000000..ec7c872648 --- /dev/null +++ b/packages/opentelemetry-metrics/test/export/Controller.test.ts @@ -0,0 +1,73 @@ +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import * as assert from 'assert'; +import * as sinon from 'sinon'; +import { MeterProvider, MetricExporter, MetricRecord } from '../../src'; +import { + ExportResult, + ExportResultCode, + setGlobalErrorHandler, +} from '@opentelemetry/core'; + +class MockExporter implements MetricExporter { + constructor(private _result: ExportResult) {} + + export( + metrics: MetricRecord[], + resultCallback: (result: ExportResult) => void + ): void { + return resultCallback(this._result); + } + + shutdown() { + return Promise.resolve(); + } +} + +describe('Controller', () => { + describe('._collect()', () => { + it('should use globalErrorHandler in case of error', done => { + const errorHandlerSpy = sinon.spy(); + setGlobalErrorHandler(errorHandlerSpy); + const expectedError = new Error('Failed to export'); + const meter = new MeterProvider({ + exporter: new MockExporter({ + code: ExportResultCode.FAILED, + error: expectedError, + }), + }).getMeter('test-console-metric-exporter'); + const counter = meter + .createCounter('counter', { + description: 'a test description', + }) + .bind({}); + counter.add(10); + + // @ts-expect-error trigger the collection from the controller + meter._controller._collect(); + // wait for result + setTimeout(() => { + assert.deepStrictEqual( + errorHandlerSpy.args[0][0].message, + expectedError.message + ); + setGlobalErrorHandler(() => {}); + return done(); + }, 0); + }); + }); +}); diff --git a/packages/opentelemetry-tracing/src/export/BatchSpanProcessor.ts b/packages/opentelemetry-tracing/src/export/BatchSpanProcessor.ts index a2373ae038..5813c302fa 100644 --- a/packages/opentelemetry-tracing/src/export/BatchSpanProcessor.ts +++ b/packages/opentelemetry-tracing/src/export/BatchSpanProcessor.ts @@ -16,7 +16,7 @@ import { context, suppressInstrumentation } from '@opentelemetry/api'; import { - ExportResult, + ExportResultCode, globalErrorHandler, unrefTimer, } from '@opentelemetry/core'; @@ -111,13 +111,12 @@ export class BatchSpanProcessor implements SpanProcessor { context.with(suppressInstrumentation(context.active()), () => { this._exporter.export(this._finishedSpans, result => { this._finishedSpans = []; - if (result === ExportResult.SUCCESS) { + if (result.code === ExportResultCode.SUCCESS) { resolve(); } else { reject( - new Error( - `BatchSpanProcessor: span export failed (status ${result})` - ) + result.error ?? + new Error('BatchSpanProcessor: span export failed') ); } }); diff --git a/packages/opentelemetry-tracing/src/export/ConsoleSpanExporter.ts b/packages/opentelemetry-tracing/src/export/ConsoleSpanExporter.ts index 8be4a90abd..003bac7113 100644 --- a/packages/opentelemetry-tracing/src/export/ConsoleSpanExporter.ts +++ b/packages/opentelemetry-tracing/src/export/ConsoleSpanExporter.ts @@ -16,7 +16,11 @@ import { SpanExporter } from './SpanExporter'; import { ReadableSpan } from './ReadableSpan'; -import { ExportResult, hrTimeToMicroseconds } from '@opentelemetry/core'; +import { + ExportResult, + ExportResultCode, + hrTimeToMicroseconds, +} from '@opentelemetry/core'; /** * This is implementation of {@link SpanExporter} that prints spans to the @@ -75,7 +79,7 @@ export class ConsoleSpanExporter implements SpanExporter { console.log(this._exportInfo(span)); } if (done) { - return done(ExportResult.SUCCESS); + return done({ code: ExportResultCode.SUCCESS }); } } } diff --git a/packages/opentelemetry-tracing/src/export/InMemorySpanExporter.ts b/packages/opentelemetry-tracing/src/export/InMemorySpanExporter.ts index 501ae11f70..4a49892899 100644 --- a/packages/opentelemetry-tracing/src/export/InMemorySpanExporter.ts +++ b/packages/opentelemetry-tracing/src/export/InMemorySpanExporter.ts @@ -16,7 +16,7 @@ import { SpanExporter } from './SpanExporter'; import { ReadableSpan } from './ReadableSpan'; -import { ExportResult } from '@opentelemetry/core'; +import { ExportResult, ExportResultCode } from '@opentelemetry/core'; /** * This class can be used for testing purposes. It stores the exported spans @@ -35,10 +35,14 @@ export class InMemorySpanExporter implements SpanExporter { spans: ReadableSpan[], resultCallback: (result: ExportResult) => void ): void { - if (this._stopped) return resultCallback(ExportResult.FAILED_NOT_RETRYABLE); + if (this._stopped) + return resultCallback({ + code: ExportResultCode.FAILED, + error: new Error('Exporter has been stopped'), + }); this._finishedSpans.push(...spans); - setTimeout(() => resultCallback(ExportResult.SUCCESS), 0); + setTimeout(() => resultCallback({ code: ExportResultCode.SUCCESS }), 0); } shutdown(): Promise { diff --git a/packages/opentelemetry-tracing/src/export/SimpleSpanProcessor.ts b/packages/opentelemetry-tracing/src/export/SimpleSpanProcessor.ts index fbf7cab872..487ccccea4 100644 --- a/packages/opentelemetry-tracing/src/export/SimpleSpanProcessor.ts +++ b/packages/opentelemetry-tracing/src/export/SimpleSpanProcessor.ts @@ -15,7 +15,7 @@ */ import { context, suppressInstrumentation } from '@opentelemetry/api'; -import { ExportResult, globalErrorHandler } from '@opentelemetry/core'; +import { ExportResultCode, globalErrorHandler } from '@opentelemetry/core'; import { Span } from '../Span'; import { SpanExporter } from './SpanExporter'; import { SpanProcessor } from '../SpanProcessor'; @@ -49,11 +49,12 @@ export class SimpleSpanProcessor implements SpanProcessor { // prevent downstream exporter calls from generating spans context.with(suppressInstrumentation(context.active()), () => { this._exporter.export([span], result => { - if (result !== ExportResult.SUCCESS) { + if (result.code !== ExportResultCode.SUCCESS) { globalErrorHandler( - new Error( - `SimpleSpanProcessor: span export failed (status ${result})` - ) + result.error ?? + new Error( + `SimpleSpanProcessor: span export failed (status ${result})` + ) ); } }); diff --git a/packages/opentelemetry-tracing/test/export/BatchSpanProcessor.test.ts b/packages/opentelemetry-tracing/test/export/BatchSpanProcessor.test.ts index 01ad030fc4..014f5edfa2 100644 --- a/packages/opentelemetry-tracing/test/export/BatchSpanProcessor.test.ts +++ b/packages/opentelemetry-tracing/test/export/BatchSpanProcessor.test.ts @@ -16,7 +16,7 @@ import { AlwaysOnSampler, - ExportResult, + ExportResultCode, loggingErrorHandler, setGlobalErrorHandler, } from '@opentelemetry/core'; @@ -224,7 +224,7 @@ describe('BatchSpanProcessor', () => { sinon.stub(exporter, 'export').callsFake((spans, callback) => { setTimeout(() => { exportedSpans = exportedSpans + spans.length; - callback(ExportResult.SUCCESS); + callback({ code: ExportResultCode.SUCCESS }); }, 0); }); @@ -235,12 +235,10 @@ describe('BatchSpanProcessor', () => { }); it('should call globalErrorHandler when exporting fails', async () => { - const expectedError = new Error( - 'BatchSpanProcessor: span export failed (status 1)' - ); + const expectedError = new Error('Exporter failed'); sinon.stub(exporter, 'export').callsFake((_, callback) => { setTimeout(() => { - callback(ExportResult.FAILED_NOT_RETRYABLE); + callback({ code: ExportResultCode.FAILED, error: expectedError }); }, 0); }); diff --git a/packages/opentelemetry-tracing/test/export/InMemorySpanExporter.test.ts b/packages/opentelemetry-tracing/test/export/InMemorySpanExporter.test.ts index 9b0a5251b4..0cb9de0e53 100644 --- a/packages/opentelemetry-tracing/test/export/InMemorySpanExporter.test.ts +++ b/packages/opentelemetry-tracing/test/export/InMemorySpanExporter.test.ts @@ -21,7 +21,7 @@ import { BasicTracerProvider, } from '../../src'; import { context, setActiveSpan } from '@opentelemetry/api'; -import { ExportResult } from '@opentelemetry/core'; +import { ExportResult, ExportResultCode } from '@opentelemetry/core'; describe('InMemorySpanExporter', () => { let memoryExporter: InMemorySpanExporter; @@ -83,7 +83,7 @@ describe('InMemorySpanExporter', () => { it('should return the success result', () => { const exorter = new InMemorySpanExporter(); exorter.export([], (result: ExportResult) => { - assert.strictEqual(result, ExportResult.SUCCESS); + assert.strictEqual(result.code, ExportResultCode.SUCCESS); }); }); @@ -93,7 +93,7 @@ describe('InMemorySpanExporter', () => { // after shutdown export should fail exorter.export([], (result: ExportResult) => { - assert.strictEqual(result, ExportResult.FAILED_NOT_RETRYABLE); + assert.strictEqual(result.code, ExportResultCode.FAILED); }); }); }); diff --git a/packages/opentelemetry-tracing/test/export/SimpleSpanProcessor.test.ts b/packages/opentelemetry-tracing/test/export/SimpleSpanProcessor.test.ts index e647068d8b..6a5cf80c90 100644 --- a/packages/opentelemetry-tracing/test/export/SimpleSpanProcessor.test.ts +++ b/packages/opentelemetry-tracing/test/export/SimpleSpanProcessor.test.ts @@ -22,7 +22,7 @@ import { TraceFlags, } from '@opentelemetry/api'; import { - ExportResult, + ExportResultCode, loggingErrorHandler, setGlobalErrorHandler, } from '@opentelemetry/core'; @@ -98,9 +98,7 @@ describe('SimpleSpanProcessor', () => { }); it('should call globalErrorHandler when exporting fails', async () => { - const expectedError = new Error( - 'SimpleSpanProcessor: span export failed (status 1)' - ); + const expectedError = new Error('Exporter failed'); const processor = new SimpleSpanProcessor(exporter); const spanContext: SpanContext = { traceId: 'a3cda95b652f4a1592b449d5929fda1b', @@ -117,7 +115,7 @@ describe('SimpleSpanProcessor', () => { sinon.stub(exporter, 'export').callsFake((_, callback) => { setTimeout(() => { - callback(ExportResult.FAILED_NOT_RETRYABLE); + callback({ code: ExportResultCode.FAILED, error: expectedError }); }, 0); });