Skip to content

Commit e9e565f

Browse files
committed
feat: captureScreenshot support
1 parent bc90487 commit e9e565f

File tree

10 files changed

+10192
-9017
lines changed

10 files changed

+10192
-9017
lines changed

src/client.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { NativeTransport } from './transports/native';
1313
import { createUserFeedbackEnvelope, items } from './utils/envelope';
1414
import { mergeOutcomes } from './utils/outcome';
1515
import { NATIVE } from './wrapper';
16+
import { Screenshot } from './integrations/screenshot';
1617

1718

1819
/**
@@ -59,12 +60,13 @@ export class NativescriptClient extends BaseClient<NativescriptClientOptions> {
5960
/**
6061
* @inheritDoc
6162
*/
62-
public eventFromException(_exception: unknown, _hint?: EventHint): PromiseLike<Event> {
63+
public eventFromException(exception: unknown, hint?: EventHint): PromiseLike<Event> {
6364
// N put stackTrace in "stackTrace" instead of "stacktrace"
64-
if (_exception['stackTrace']) {
65-
_exception['stacktrace'] = _exception['stackTrace'];
65+
if (exception['stackTrace']) {
66+
exception['stacktrace'] = exception['stackTrace'];
6667
}
67-
return this._browserClient.eventFromException(_exception, _hint);
68+
Screenshot.attachScreenshotToEventHint(hint, this._options);
69+
return this._browserClient.eventFromException(exception, hint);
6870
}
6971

7072
/**

src/integrations/nativescripterrorhandlers.ts

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import { getCurrentHub } from '@sentry/core';
22
import { eventFromUnknownInput } from '@sentry/browser/esm/eventbuilder';
3-
import { Integration, SeverityLevel } from '@sentry/types';
3+
import { EventHint, Integration, SeverityLevel } from '@sentry/types';
44
import { NATIVE } from '../wrapper';
55
import { addExceptionMechanism, getGlobalObject, logger } from '@sentry/utils';
66

77
import { NativescriptClient } from '../client';
88

99
import {Application, Trace} from '@nativescript/core';
10+
import { Screenshot } from './screenshot';
1011

1112
/** NativescriptErrorHandlers Options */
1213
export interface NativescriptErrorHandlersOptions {
@@ -123,28 +124,34 @@ export class NativescriptErrorHandlers implements Integration {
123124

124125
return;
125126
}
127+
128+
129+
// We override client.eventFromException because it is async function
130+
// while not needed and we want to be sync
126131
if (error['stackTrace']) {
127132
error['stacktrace'] = error['stackTrace'];
128133
}
129-
// const syntheticException = (hint && hint.syntheticException) || undefined;
130-
const event = eventFromUnknownInput(client.getOptions().stackParser, error, undefined, true);
134+
let hint: EventHint = {
135+
originalException: error
136+
};
137+
const syntheticException = (hint && hint.syntheticException) || undefined;
138+
hint = Screenshot.attachScreenshotToEventHint(hint, client.getOptions());
139+
const event = eventFromUnknownInput(client.getOptions().stackParser, error, syntheticException, client.getOptions().attachStacktrace);
131140
addExceptionMechanism(event); // defaults to { type: 'generic', handled: true }
132141
event.level = 'error';
133-
// const event = await client.eventFromException(error, {
134-
// originalException: error
135-
// });
142+
if (hint && hint.event_id) {
143+
event.event_id = hint.event_id;
144+
}
136145

137146
if (isFatal) {
138147
event.level = 'fatal' as SeverityLevel;
139-
140148
addExceptionMechanism(event, {
141149
handled: false,
142150
type: 'onerror',
143151
});
144152
}
145153

146-
const result = client.captureEvent(event);
147-
console.log('globalHander2', result, Object.keys(event));
154+
client.captureEvent(event);
148155
} catch (error) {
149156
console.error(error);
150157
}

src/integrations/screenshot.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { EventHint, Integration } from '@sentry/types';
2+
import { resolvedSyncPromise } from '@sentry/utils';
3+
4+
import { NATIVE } from '../wrapper';
5+
6+
/** Adds screenshots to error events */
7+
export class Screenshot implements Integration {
8+
/**
9+
* @inheritDoc
10+
*/
11+
public static id: string = 'Screenshot';
12+
13+
/**
14+
* @inheritDoc
15+
*/
16+
public name: string = Screenshot.id;
17+
18+
/**
19+
* If enabled attaches a screenshot to the event hint.
20+
*/
21+
public static attachScreenshotToEventHint(
22+
hint: EventHint,
23+
{ attachScreenshot }: { attachScreenshot?: boolean },
24+
): EventHint {
25+
if (!attachScreenshot) {
26+
return (hint);
27+
}
28+
29+
const screenshots = NATIVE.captureScreenshot();
30+
if (screenshots !== null && screenshots.length > 0) {
31+
hint.attachments = [
32+
...screenshots,
33+
...(hint?.attachments || []),
34+
];
35+
}
36+
console.log('attachScreenshotToEventHint', screenshots, hint.attachments);
37+
return hint;
38+
}
39+
40+
/**
41+
* @inheritDoc
42+
*/
43+
// eslint-disable-next-line @typescript-eslint/no-empty-function
44+
public setupOnce(): void {}
45+
}

src/options.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,13 @@ export interface BaseNativescriptOptions {
5151
/** When enabled, all the threads are automatically attached to all logged events on Android */
5252
attachThreads?: boolean;
5353

54+
/**
55+
* When enabled and a user experiences an error, Sentry provides the ability to take a screenshot and include it as an attachment.
56+
*
57+
* @default false
58+
*/
59+
attachScreenshot?: boolean;
60+
5461
/**
5562
* When enabled, certain personally identifiable information (PII) is added by active integrations.
5663
*

src/sdk.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { makeUtf8TextEncoder } from './transports/TextEncoder';
1818
import { safeFactory, safeTracesSampler } from './utils/safe';
1919
import { NATIVE } from './wrapper';
2020
import { parseErrorStack } from './integrations/debugsymbolicator';
21+
import { Screenshot } from './integrations/screenshot';
2122

2223

2324
const STACKTRACE_LIMIT = 50;
@@ -160,6 +161,9 @@ export function init(passedOptions: NativescriptOptions): void {
160161
defaultIntegrations.push(new NativescriptTracing());
161162
}
162163
}
164+
if (options.attachScreenshot) {
165+
defaultIntegrations.push(new Screenshot());
166+
}
163167
}
164168
options.integrations = getIntegrationsToSetup({
165169
integrations: safeFactory(passedOptions.integrations, { loggerMessage: 'The integrations threw an error' }),

0 commit comments

Comments
 (0)