Skip to content

Commit 33e8d47

Browse files
committed
feat: Return event_id from capture calls
1 parent f7b6452 commit 33e8d47

File tree

11 files changed

+117
-28
lines changed

11 files changed

+117
-28
lines changed

packages/browser/src/backend.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ export class BrowserBackend implements Backend {
9797

9898
event = {
9999
...event,
100+
event_id: hint && hint.event_id,
100101
exception: {
101102
...event.exception,
102103
mechanism: {
@@ -114,6 +115,7 @@ export class BrowserBackend implements Backend {
114115
*/
115116
public async eventFromMessage(message: string, level?: Severity, hint?: SentryEventHint): Promise<SentryEvent> {
116117
const event: SentryEvent = {
118+
event_id: hint && hint.event_id,
117119
fingerprint: [message],
118120
level,
119121
message,

packages/browser/test/index.test.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
init,
1313
Scope,
1414
SentryEvent,
15+
Status,
1516
} from '../src';
1617

1718
const dsn = 'https://[email protected]/4291';
@@ -64,7 +65,7 @@ describe('SentryBrowser', () => {
6465
let s: sinon.SinonStub;
6566

6667
beforeEach(() => {
67-
s = stub(BrowserBackend.prototype, 'sendEvent').returns(Promise.resolve(200));
68+
s = stub(BrowserBackend.prototype, 'sendEvent').returns(Promise.resolve({ status: Status.Success }));
6869
});
6970

7071
afterEach(() => {
@@ -96,7 +97,7 @@ describe('SentryBrowser', () => {
9697
let s: sinon.SinonStub;
9798

9899
beforeEach(() => {
99-
s = stub(BrowserBackend.prototype, 'sendEvent').returns(Promise.resolve(200));
100+
s = stub(BrowserBackend.prototype, 'sendEvent').returns(Promise.resolve({ status: Status.Success }));
100101
});
101102

102103
afterEach(() => {

packages/core/src/base.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -116,17 +116,22 @@ export abstract class BaseClient<B extends Backend, O extends Options> implement
116116
/**
117117
* @inheritDoc
118118
*/
119-
public async captureException(exception: any, hint?: SentryEventHint, scope?: Scope): Promise<void> {
119+
public async captureException(exception: any, hint?: SentryEventHint, scope?: Scope): Promise<SentryResponse> {
120120
const event = await this.getBackend().eventFromException(exception, hint);
121-
await this.captureEvent(event, hint, scope);
121+
return this.captureEvent(event, hint, scope);
122122
}
123123

124124
/**
125125
* @inheritDoc
126126
*/
127-
public async captureMessage(message: string, level?: Severity, hint?: SentryEventHint, scope?: Scope): Promise<void> {
127+
public async captureMessage(
128+
message: string,
129+
level?: Severity,
130+
hint?: SentryEventHint,
131+
scope?: Scope,
132+
): Promise<SentryResponse> {
128133
const event = await this.getBackend().eventFromMessage(message, level, hint);
129-
await this.captureEvent(event, hint, scope);
134+
return this.captureEvent(event, hint, scope);
130135
}
131136

132137
/**
@@ -225,7 +230,9 @@ export abstract class BaseClient<B extends Backend, O extends Options> implement
225230
request.url = truncate(request.url, MAX_URL_LENGTH);
226231
}
227232

228-
prepared.event_id = uuid4();
233+
if (prepared.event_id === undefined) {
234+
prepared.event_id = uuid4();
235+
}
229236

230237
// This should be the last thing called, since we want that
231238
// {@link Hub.addEventProcessor} gets the finished prepared event.
@@ -287,7 +294,9 @@ export abstract class BaseClient<B extends Backend, O extends Options> implement
287294
status: Status.Skipped,
288295
};
289296
}
297+
290298
const response = await send(finalEvent);
299+
response.event = finalEvent;
291300

292301
if (response.status === Status.RateLimit) {
293302
// TODO: Handle rate limits and maintain a queue. For now, we require SDK

packages/core/src/interfaces.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -139,9 +139,9 @@ export interface Client<O extends Options = Options> {
139139
* @param exception An exception-like object.
140140
* @param hint May contain additional informartion about the original exception.
141141
* @param scope An optional scope containing event metadata.
142-
* @returns The created event id.
142+
* @returns SentryResponse status and event
143143
*/
144-
captureException(exception: any, hint?: SentryEventHint, scope?: Scope): Promise<void>;
144+
captureException(exception: any, hint?: SentryEventHint, scope?: Scope): Promise<SentryResponse>;
145145

146146
/**
147147
* Captures a message event and sends it to Sentry.
@@ -150,17 +150,17 @@ export interface Client<O extends Options = Options> {
150150
* @param level Define the level of the message.
151151
* @param hint May contain additional informartion about the original exception.
152152
* @param scope An optional scope containing event metadata.
153-
* @returns The created event id.
153+
* @returns SentryResponse status and event
154154
*/
155-
captureMessage(message: string, level?: Severity, hint?: SentryEventHint, scope?: Scope): Promise<void>;
155+
captureMessage(message: string, level?: Severity, hint?: SentryEventHint, scope?: Scope): Promise<SentryResponse>;
156156

157157
/**
158158
* Captures a manually created event and sends it to Sentry.
159159
*
160160
* @param event The event to send to Sentry.
161161
* @param hint May contain additional informartion about the original exception.
162162
* @param scope An optional scope containing event metadata.
163-
* @returns The created event id.
163+
* @returns SentryResponse status and event
164164
*/
165165
captureEvent(event: SentryEvent, hint?: SentryEventHint, scope?: Scope): Promise<SentryResponse>;
166166

packages/hub/src/hub.ts

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Breadcrumb, SentryEvent, SentryEventHint, Severity } from '@sentry/types';
2+
import { uuid4 } from '@sentry/utils/misc';
23
import { Layer } from './interfaces';
34
import { Scope } from './scope';
45

@@ -8,7 +9,7 @@ import { Scope } from './scope';
89
* WARNING: This number should only be incresed when the global interface
910
* changes a and new methods are introduced.
1011
*/
11-
export const API_VERSION = 2;
12+
export const API_VERSION = 3;
1213

1314
/**
1415
* Internal class used to make sure we always have the latest internal functions
@@ -165,9 +166,15 @@ export class Hub {
165166
*
166167
* @param exception An exception-like object.
167168
* @param hint May contain additional informartion about the original exception.
169+
* @returns The generated eventId.
168170
*/
169-
public captureException(exception: any, hint?: SentryEventHint): void {
170-
this.invokeClientAsync('captureException', exception, hint);
171+
public captureException(exception: any, hint?: SentryEventHint): string {
172+
const eventId = uuid4();
173+
this.invokeClientAsync('captureException', exception, {
174+
...hint,
175+
event_id: eventId,
176+
});
177+
return eventId;
171178
}
172179

173180
/**
@@ -176,18 +183,28 @@ export class Hub {
176183
* @param message The message to send to Sentry.
177184
* @param level Define the level of the message.
178185
* @param hint May contain additional informartion about the original exception.
186+
* @returns The generated eventId.
179187
*/
180-
public captureMessage(message: string, level?: Severity, hint?: SentryEventHint): void {
181-
this.invokeClientAsync('captureMessage', message, level, hint);
188+
public captureMessage(message: string, level?: Severity, hint?: SentryEventHint): string {
189+
const eventId = uuid4();
190+
this.invokeClientAsync('captureMessage', message, level, {
191+
...hint,
192+
event_id: eventId,
193+
});
194+
return eventId;
182195
}
183196

184197
/**
185198
* Captures a manually created event and sends it to Sentry.
186199
*
187200
* @param event The event to send to Sentry.
188201
*/
189-
public captureEvent(event: SentryEvent): void {
190-
this.invokeClientAsync('captureEvent', event);
202+
public captureEvent(event: SentryEvent): string {
203+
const eventId = uuid4();
204+
this.invokeClientAsync('captureEvent', event, {
205+
event_id: eventId,
206+
});
207+
return eventId;
191208
}
192209

193210
/**

packages/hub/test/lib/hub.test.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,4 +247,28 @@ describe('Hub', () => {
247247
expect(final!.dist).toEqual('1');
248248
}
249249
});
250+
251+
test('captureException should set event_id in hint', () => {
252+
const hub = new Hub();
253+
const spy = jest.spyOn(hub as any, 'invokeClientAsync');
254+
hub.captureException('a');
255+
expect(spy.mock.calls[0][2]!.event_id).toBeTruthy();
256+
});
257+
258+
test('captureMessage should set event_id in hint', () => {
259+
const hub = new Hub();
260+
const spy = jest.spyOn(hub as any, 'invokeClientAsync');
261+
hub.captureMessage('a');
262+
expect(spy.mock.calls[0][3]!.event_id).toBeTruthy();
263+
});
264+
265+
test('captureEvent should set event_id in hint', () => {
266+
const event: SentryEvent = {
267+
extra: { b: 3 },
268+
};
269+
const hub = new Hub();
270+
const spy = jest.spyOn(hub as any, 'invokeClientAsync');
271+
hub.captureEvent(event);
272+
expect(spy.mock.calls[0][2]!.event_id).toBeTruthy();
273+
});
250274
});

packages/minimal/src/index.ts

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,51 +6,55 @@ import { Breadcrumb, SentryEvent, Severity } from '@sentry/types';
66
* @param method function to call on hub.
77
* @param args to pass to function.
88
*/
9-
function callOnHub(method: string, ...args: any[]): void {
9+
function callOnHub<T>(method: string, ...args: any[]): T {
1010
const hub = getCurrentHub();
1111
if (hub && hub[method as keyof Hub]) {
12-
(hub[method as keyof Hub] as any)(...args);
12+
return (hub[method as keyof Hub] as any)(...args);
1313
}
14+
throw new Error(`No hub defined or ${method} was not found on the hub, please open a bug report.`);
1415
}
1516

1617
/**
1718
* Captures an exception event and sends it to Sentry.
1819
*
1920
* @param exception An exception-like object.
21+
* @returns The generated eventId.
2022
*/
21-
export function captureException(exception: any): void {
23+
export function captureException(exception: any): string {
2224
let syntheticException: Error;
2325
try {
2426
throw new Error('Sentry syntheticException');
2527
} catch (exception) {
2628
syntheticException = exception as Error;
2729
}
28-
callOnHub('captureException', exception, { syntheticException });
30+
return callOnHub('captureException', exception, { syntheticException });
2931
}
3032

3133
/**
3234
* Captures a message event and sends it to Sentry.
3335
*
3436
* @param message The message to send to Sentry.
3537
* @param level Define the level of the message.
38+
* @returns The generated eventId.
3639
*/
37-
export function captureMessage(message: string, level?: Severity): void {
40+
export function captureMessage(message: string, level?: Severity): string {
3841
let syntheticException: Error;
3942
try {
4043
throw new Error(message);
4144
} catch (exception) {
4245
syntheticException = exception as Error;
4346
}
44-
callOnHub('captureMessage', message, level, { syntheticException });
47+
return callOnHub('captureMessage', message, level, { syntheticException });
4548
}
4649

4750
/**
4851
* Captures a manually created event and sends it to Sentry.
4952
*
5053
* @param event The event to send to Sentry.
54+
* @returns The generated eventId.
5155
*/
52-
export function captureEvent(event: SentryEvent): void {
53-
callOnHub('captureEvent', event);
56+
export function captureEvent(event: SentryEvent): string {
57+
return callOnHub('captureEvent', event);
5458
}
5559

5660
/**

packages/minimal/test/lib/minimal.test.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,18 @@ describe('Minimal', () => {
1919
});
2020

2121
describe('Capture', () => {
22+
test('Return an event_id', () => {
23+
const client = {
24+
captureException: jest.fn(async () => Promise.resolve()),
25+
};
26+
getCurrentHub().withScope(() => {
27+
getCurrentHub().bindClient(client);
28+
const e = new Error('test exception');
29+
const eventId = captureException(e);
30+
expect(eventId).toBeTruthy();
31+
});
32+
});
33+
2234
test('Exception', () => {
2335
const client = {
2436
captureException: jest.fn(async () => Promise.resolve()),

packages/node/src/backend.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,18 @@ export class NodeBackend implements Backend {
5353

5454
const event: SentryEvent = await parseError(ex as Error);
5555

56-
return event;
56+
return {
57+
...event,
58+
event_id: hint && hint.event_id,
59+
};
5760
}
5861

5962
/**
6063
* @inheritDoc
6164
*/
6265
public async eventFromMessage(message: string, level?: Severity, hint?: SentryEventHint): Promise<SentryEvent> {
6366
const event: SentryEvent = {
67+
event_id: hint && hint.event_id,
6468
fingerprint: [message],
6569
level,
6670
message,

packages/types/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ export interface Integration {
210210
/** JSDoc */
211211
export interface SentryResponse {
212212
status: Status;
213+
event?: SentryEvent;
213214
}
214215

215216
/** JSDoc */
@@ -284,6 +285,7 @@ export interface SentryWrappedFunction extends Function {
284285

285286
/** JSDoc */
286287
export interface SentryEventHint {
288+
event_id?: string;
287289
syntheticException?: Error | null;
288290
originalException?: Error | null;
289291
data?: any;

yarn.lock

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1979,6 +1979,10 @@ colors@^1.1.0:
19791979
version "1.3.0"
19801980
resolved "https://registry.yarnpkg.com/colors/-/colors-1.3.0.tgz#5f20c9fef6945cb1134260aab33bfbdc8295e04e"
19811981

1982+
colors@~0.6.0:
1983+
version "0.6.2"
1984+
resolved "https://registry.yarnpkg.com/colors/-/colors-0.6.2.tgz#2423fe6678ac0c5dae8852e5d0e5be08c997abcc"
1985+
19821986
columnify@^1.5.4:
19831987
version "1.5.4"
19841988
resolved "https://registry.yarnpkg.com/columnify/-/columnify-1.5.4.tgz#4737ddf1c7b69a8a7c340570782e947eec8e78bb"
@@ -4604,6 +4608,16 @@ karma-coverage@^1.1.1:
46044608
minimatch "^3.0.0"
46054609
source-map "^0.5.1"
46064610

4611+
4612+
version "0.0.3"
4613+
resolved "https://registry.yarnpkg.com/karma-failed-reporter/-/karma-failed-reporter-0.0.3.tgz#4532ec9652c9fe297d0b72d08d9cade9725ef733"
4614+
dependencies:
4615+
colors "~0.6.0"
4616+
4617+
karma-firefox-launcher@^1.1.0:
4618+
version "1.1.0"
4619+
resolved "https://registry.yarnpkg.com/karma-firefox-launcher/-/karma-firefox-launcher-1.1.0.tgz#2c47030452f04531eb7d13d4fc7669630bb93339"
4620+
46074621
karma-mocha-reporter@^2.2.5:
46084622
version "2.2.5"
46094623
resolved "https://registry.yarnpkg.com/karma-mocha-reporter/-/karma-mocha-reporter-2.2.5.tgz#15120095e8ed819186e47a0b012f3cd741895560"

0 commit comments

Comments
 (0)