Skip to content

Commit e1e4d90

Browse files
authored
telemetry: Set transaction status based on status code when aborting (#836)
1 parent f89b4f8 commit e1e4d90

File tree

2 files changed

+74
-1
lines changed

2 files changed

+74
-1
lines changed

src/utils/clack-utils.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,10 @@ export async function abort(message?: string, status?: number): Promise<never> {
112112
clack.outro(message ?? 'Wizard setup cancelled.');
113113
const sentryHub = Sentry.getCurrentHub();
114114
const sentryTransaction = sentryHub.getScope().getTransaction();
115-
sentryTransaction?.setStatus('aborted');
115+
// 'cancelled' doesn't increase the `failureRate()` shown in the Sentry UI
116+
// 'aborted' increases the failure rate
117+
// see: https://docs.sentry.io/product/insights/overview/metrics/#failure-rate
118+
sentryTransaction?.setStatus(status === 0 ? 'cancelled' : 'aborted');
116119
sentryTransaction?.finish();
117120
const sentrySession = sentryHub.getScope().getSession();
118121
if (sentrySession) {

test/utils/clack-utils.test.ts

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import {
2+
abort,
23
askForToolConfigPath,
34
askForWizardLogin,
45
createNewConfigFile,
@@ -14,6 +15,8 @@ import axios from 'axios';
1415
// @ts-ignore - clack is ESM and TS complains about that. It works though
1516
import * as clack from '@clack/prompts';
1617

18+
import * as Sentry from '@sentry/node';
19+
1720
jest.mock('node:child_process', () => ({
1821
__esModule: true,
1922
...jest.requireActual('node:child_process'),
@@ -287,3 +290,70 @@ describe('askForWizardLogin', () => {
287290
expect(clack.confirm).not.toHaveBeenCalled();
288291
});
289292
});
293+
294+
describe('abort', () => {
295+
const sentryTxn = {
296+
setStatus: jest.fn(),
297+
finish: jest.fn(),
298+
};
299+
300+
let sentrySession = {
301+
status: 999,
302+
};
303+
304+
beforeEach(() => {
305+
jest.clearAllMocks();
306+
sentrySession = {
307+
status: 999,
308+
};
309+
});
310+
311+
jest.spyOn(Sentry, 'getCurrentHub').mockReturnValue({
312+
getScope: () => ({
313+
// @ts-expect-error - don't care about the rest of the required props value
314+
getTransaction: () => sentryTxn,
315+
// @ts-expect-error - don't care about the rest of the required props value
316+
getSession: () => sentrySession,
317+
}),
318+
captureSession: jest.fn(),
319+
});
320+
321+
const flushSpy = jest.fn();
322+
jest.spyOn(Sentry, 'flush').mockImplementation(flushSpy);
323+
324+
it('ends the process with an error exit code by default', async () => {
325+
// @ts-ignore - jest doesn't like the empty function
326+
// eslint-disable-next-line @typescript-eslint/no-empty-function
327+
const exitSpy = jest.spyOn(process, 'exit').mockImplementation(() => {});
328+
329+
await abort();
330+
331+
expect(exitSpy).toHaveBeenCalledWith(1);
332+
333+
expect(clackMock.outro).toHaveBeenCalledTimes(1);
334+
expect(clackMock.outro).toHaveBeenCalledWith('Wizard setup cancelled.');
335+
336+
expect(sentryTxn.setStatus).toHaveBeenLastCalledWith('aborted');
337+
expect(sentryTxn.finish).toHaveBeenCalledTimes(1);
338+
expect(sentrySession.status).toBe('crashed');
339+
expect(flushSpy).toHaveBeenLastCalledWith(3000);
340+
});
341+
342+
it('ends the process with a custom exit code and message if provided', async () => {
343+
// @ts-ignore - jest doesn't like the empty function
344+
// eslint-disable-next-line @typescript-eslint/no-empty-function
345+
const exitSpy = jest.spyOn(process, 'exit').mockImplementation(() => {});
346+
347+
await abort('Bye', 0);
348+
349+
expect(exitSpy).toHaveBeenCalledWith(0);
350+
351+
expect(clackMock.outro).toHaveBeenCalledTimes(1);
352+
expect(clackMock.outro).toHaveBeenCalledWith('Bye');
353+
354+
expect(sentryTxn.setStatus).toHaveBeenLastCalledWith('cancelled');
355+
expect(sentryTxn.finish).toHaveBeenCalledTimes(1);
356+
expect(sentrySession.status).toBe('abnormal');
357+
expect(flushSpy).toHaveBeenLastCalledWith(3000);
358+
});
359+
});

0 commit comments

Comments
 (0)