Skip to content

Commit b3f8c5f

Browse files
authored
chore(connections): add error code cause chain to connection failed telemetry COMPASS-9527 (#7136)
1 parent ec74f26 commit b3f8c5f

File tree

4 files changed

+74
-0
lines changed

4 files changed

+74
-0
lines changed

packages/compass-connections/src/stores/connections-store-redux.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import {
4040
isEndOfLifeVersion,
4141
} from '../utils/end-of-life-server';
4242
import type { ImportConnectionOptions } from '@mongodb-js/connection-storage/provider';
43+
import { getErrorCodeCauseChain } from '../utils/telemetry';
4344

4445
export type ConnectionsEventMap = {
4546
connected: (
@@ -1278,6 +1279,7 @@ const connectionAttemptError = (
12781279
async () => {
12791280
const trackParams = {
12801281
error_code: err.code,
1282+
error_code_cause_chain: getErrorCodeCauseChain(err),
12811283
error_name: err.codeName ?? err.name,
12821284
};
12831285
if (connectionInfo) {

packages/compass-connections/src/utils/telemetry.spec.tsx

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
trackConnectionDisconnectedEvent,
44
trackConnectionCreatedEvent,
55
trackConnectionRemovedEvent,
6+
getErrorCodeCauseChain,
67
} from './telemetry';
78
import { expect } from 'chai';
89
import type { ConnectionInfo } from '@mongodb-js/connection-storage/renderer';
@@ -64,4 +65,47 @@ describe('Connections telemetry', function () {
6465
expect(event).to.equal('Connection Removed');
6566
expect(properties).to.deep.equal(expected);
6667
});
68+
69+
describe('#getErrorCodeCauseChain', function () {
70+
it('should return undefined when no error', function () {
71+
const result = getErrorCodeCauseChain(undefined);
72+
expect(result).to.be.undefined;
73+
});
74+
75+
it('should return undefined when there are no error codes', function () {
76+
const result = getErrorCodeCauseChain({});
77+
expect(result).to.be.undefined;
78+
});
79+
80+
it('should return an array with the error code', function () {
81+
const error: any = new Error('Test error');
82+
error.code = 123;
83+
84+
const result = getErrorCodeCauseChain(error);
85+
expect(result).to.deep.equal([123]);
86+
});
87+
88+
it('should return an array of error codes from the cause chain', function () {
89+
const error: Error & { code?: number } = new Error('Test error');
90+
error.code = 123;
91+
92+
// No code / codeName on error two.
93+
const errorTwo = new Error('Test error two');
94+
95+
const errorThree: Error & { codeName?: string } = new Error(
96+
'Test error three'
97+
);
98+
errorThree.codeName = 'PINEAPPLE';
99+
100+
const errorFour: Error & { code?: number } = new Error('Test error four');
101+
errorFour.code = 1111;
102+
103+
error.cause = errorTwo;
104+
errorTwo.cause = errorThree;
105+
errorThree.cause = errorFour;
106+
107+
const result = getErrorCodeCauseChain(error);
108+
expect(result).to.deep.equal([123, 'PINEAPPLE', 1111]);
109+
});
110+
});
67111
});

packages/compass-connections/src/utils/telemetry.tsx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,25 @@ export function trackConnectionRemovedEvent(
2727
): void {
2828
track('Connection Removed', {}, connectionInfo);
2929
}
30+
31+
export function getErrorCodeCauseChain(
32+
err: unknown
33+
): (string | number)[] | undefined {
34+
const errorCodesInCauseChain: (string | number)[] = [];
35+
let current = err;
36+
37+
while (current && typeof current === 'object') {
38+
if ('code' in current && current.code) {
39+
errorCodesInCauseChain.push(current.code as string | number);
40+
} else if ('codeName' in current && current.codeName) {
41+
errorCodesInCauseChain.push(current.codeName as string | number);
42+
}
43+
current = (current as { cause?: unknown }).cause;
44+
}
45+
46+
if (errorCodesInCauseChain.length === 0) {
47+
return undefined;
48+
}
49+
50+
return errorCodesInCauseChain;
51+
}

packages/compass-telemetry/src/telemetry-events.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -832,6 +832,12 @@ type ConnectionFailedEvent = ConnectionScopedEvent<{
832832
* The error name.
833833
*/
834834
error_name: string;
835+
836+
/**
837+
* The error codes (or code names) from the error's cause chain.
838+
* The driver and the OIDC library we use are two places that use cause chains.
839+
*/
840+
error_code_cause_chain: (string | number)[] | undefined;
835841
} & ExtraConnectionData;
836842
}>;
837843

0 commit comments

Comments
 (0)