Skip to content

Commit

Permalink
chore(instrumentation-undici): add tests for error capturing
Browse files Browse the repository at this point in the history
  • Loading branch information
david-luna committed Jan 26, 2024
1 parent c5ca3dc commit 8ebdfc8
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/
import * as assert from 'assert';

import { context, propagation } from '@opentelemetry/api';
import { SpanStatusCode, context, propagation } from '@opentelemetry/api';
import { AsyncHooksContextManager } from '@opentelemetry/context-async-hooks';
import {
InMemorySpanExporter,
Expand Down Expand Up @@ -55,11 +55,18 @@ describe('UndiciInstrumentation `fetch` tests', function () {
context.setGlobalContextManager(new AsyncHooksContextManager().enable());
mockServer.start(done);
mockServer.mockListener((req, res) => {
res.statusCode = 200;
res.setHeader('content-type', 'application/json');
res.setHeader('foo-server', 'bar');
res.write(JSON.stringify({ success: true }));
res.end();
if (req.url === '/throw') {
res.statusCode = 500;
res.setHeader('content-type', 'text/plain');
res.write('Intenal server error :(');
res.end();
} else {
res.statusCode = 200;
res.setHeader('content-type', 'application/json');
res.setHeader('foo-server', 'bar');
res.write(JSON.stringify({ success: true }));
res.end();
}
});
});

Expand Down Expand Up @@ -95,7 +102,8 @@ describe('UndiciInstrumentation `fetch` tests', function () {
instrumentation.enable();
});
afterEach(function () {
instrumentation.disable();
// Empty configuration & disable
instrumentation.setConfig({ enabled: false });
});

it('should create valid spans even if the configuration hooks fail', async function () {
Expand Down Expand Up @@ -142,9 +150,6 @@ describe('UndiciInstrumentation `fetch` tests', function () {
let spans = memoryExporter.getFinishedSpans();
assert.strictEqual(spans.length, 0);

// Empty configuration
instrumentation.setConfig({ enabled: true });

const fetchUrl = `${protocol}://${hostname}:${mockServer.port}/?query=test`;
const response = await fetch(fetchUrl);

Expand Down Expand Up @@ -235,6 +240,7 @@ describe('UndiciInstrumentation `fetch` tests', function () {
);
});

// TODO: another test with a parent span. Check HTTP tests
it('should not create spans without parent if configured', async function () {
let spans = memoryExporter.getFinishedSpans();
assert.strictEqual(spans.length, 0);
Expand All @@ -250,5 +256,40 @@ describe('UndiciInstrumentation `fetch` tests', function () {
spans = memoryExporter.getFinishedSpans();
assert.strictEqual(spans.length, 0, 'no spans are created');
});


it('should capture erros from the server', async function () {
let spans = memoryExporter.getFinishedSpans();
assert.strictEqual(spans.length, 0);

// const fetchUrl = `${protocol}://${hostname}:${mockServer.port}/throw`;
let fetchError;
try {
const fetchUrl = `http://unexistent-host-name/path`;
await fetch(fetchUrl);
} catch (err) {
// Expected error since webdav schema is not supported
fetchError = err;
}

await new Promise((r) => setTimeout(r, 10));


spans = memoryExporter.getFinishedSpans();
const span = spans[0];
assert.ok(span, 'a span is present');
assert.strictEqual(spans.length, 1);
assertSpan(span, {
hostname: 'unexistent-host-name',
httpMethod: 'GET',
path: '/path',
error: fetchError,
noNetPeer: true, // do not check network attribs
forceStatus: {
code: SpanStatusCode.ERROR,
message: 'getaddrinfo ENOTFOUND unexistent-host-name'
}
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export const assertSpan = (
validations: {
httpStatusCode?: number;
httpMethod: string;
resHeaders: Headers;
resHeaders?: Headers;
hostname: string;
reqHeaders?: Headers;
path?: string | null;
Expand Down Expand Up @@ -101,15 +101,15 @@ export const assertSpan = (
assert.deepStrictEqual(
span.status,
validations.forceStatus || {
code: isStatusUnset ? SpanStatusCode.UNSET : SpanStatusCode.ERROR
code: isStatusUnset ? SpanStatusCode.UNSET : SpanStatusCode.ERROR,
},
'span status is correct'
);

assert.ok(span.endTime, 'must be finished');
assert.ok(hrTimeToNanoseconds(span.duration) > 0, 'must have positive duration');

const contentLengthHeader = validations.resHeaders.get('content-length');
const contentLengthHeader = validations.resHeaders?.get('content-length');
if (contentLengthHeader) {
const contentLength = Number(contentLengthHeader);

Expand Down

0 comments on commit 8ebdfc8

Please sign in to comment.