Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 39 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,47 @@ Version 10 of the Sentry JavaScript SDK primarily focuses on upgrading underlyin

Version 10 of the SDK is compatible with Sentry self-hosted versions 24.4.2 or higher (unchanged from v9). Lower versions may continue to work, but may not support all features.

### Init changed for Sentry Vue and Nuxt

Instead of adding the Nuxt/Vue options into Sentry.init options, you will now have to add it inside `siblingOptions`, this only applies to parameters specific to the respective SDK, other SDKs like React or Angular won't have to do that:

before

```typescript
Sentry.init({
app: app,
attachErrorHandler: false,
dsn: '...',
enableLogs: true,...
}, vueInit);
```

after

```typescript
Sentry.init({
dsn: '...',
enableLogs: true,
siblingOptions: {
vueOptions: {
app: app,
attachErrorHandler: false,
...
}
},
...
}, vueInit);

```

### Features

- Add Fallback to JavaScript SDK when Native SDK fails to initialize ([#1043](https://github.com/getsentry/sentry-capacitor/pull/1043))
- Add spotlight integration `spotlightIntegration`. ([#1039](https://github.com/getsentry/sentry-capacitor/pull/1039))

### Bugfix
### Fixes

- Init now showing the correct JSDoc for Vue/Nuxt init parameters. ([#1046](https://github.com/getsentry/sentry-capacitor/pull/1046))
- Replays/Logs/Sessions now have the `capacitor` SDK name as the source of the event. ([#1043](https://github.com/getsentry/sentry-capacitor/pull/1043))
- Sentry Capacitor integrations are now exposed to `@sentry/capacitor` ([#1039](https://github.com/getsentry/sentry-capacitor/pull/1039))

Expand Down Expand Up @@ -56,6 +90,10 @@ Sentry.init({
});
```

### Removed Options

- `_experimental.enableLogs` was removed, please use the options `enableLogs` from `CapacitorOptions`.

For more informations, please go to the following link: https://docs.sentry.io/platforms/javascript/migration/v9-to-v10

### Dependencies
Expand Down
12 changes: 9 additions & 3 deletions example/ionic-vue3/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ const app = createApp(App)


Sentry.init({
app,
dsn: 'https://[email protected]/4505912397660160',
integrations: [
SentryVue.vueIntegration({
Expand All @@ -59,11 +58,18 @@ Sentry.init({
enableLogs: true,
beforeSendLog: (log) => {
return log;
}
},

siblingOptions: {
vueOptions: {
app: app,
attachErrorHandler: false,
attachProps: false,
},
},
},
// Forward the init method from @sentry/vue
SentryVue.init
SentryVue.init,
);


Expand Down
7 changes: 5 additions & 2 deletions src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { NATIVE } from './wrapper';
type BrowserTransportOptions = Parameters<typeof makeFetchTransport>[0];
type TransportFactory = (transportOptions: BrowserTransportOptions) => ReturnType<typeof makeFetchTransport>;


/**
* Post setup the Capacitor client
*/
Expand Down Expand Up @@ -42,7 +41,11 @@ function PostSetupCapacitorClient() : void {
* @param originalInit - The original init function to use for the sibling SDK.
* @param customTransport - The custom transport to use.
*/
export function sdkInit<T>(browserOptions: T & BrowserOptions, nativeOptions: CapacitorOptions, originalInit: (passedOptions: T & BrowserOptions) => void, customTransport?: TransportFactory): void {
export function sdkInit(
browserOptions: BrowserOptions,
nativeOptions: CapacitorOptions,
originalInit: (passedOptions: BrowserOptions) => void,
customTransport?: TransportFactory): void {
// We first initialize the NATIVE SDK to avoid the Javascript SDK to invoke any
// feature from the NATIVE SDK without the options being set.
// eslint-disable-next-line @typescript-eslint/no-floating-promises
Expand Down
9 changes: 3 additions & 6 deletions src/nativeOptions.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Capacitor } from '@capacitor/core';
import type { BrowserOptions } from '@sentry/browser';
import type { CapacitorOptions } from './options';
import { getCurrentSpotlightUrl } from './utils/webViewUrl';

Expand Down Expand Up @@ -60,12 +59,10 @@ function iOSParameters(options: CapacitorOptions): CapacitorOptions {
: {};
}
// Browser options added so options.enableLogs is exposed.
function LogParameters(options: CapacitorOptions & BrowserOptions ): CapacitorLoggerOptions | undefined {
// eslint-disable-next-line deprecation/deprecation
const shouldEnable = options.enableLogs as boolean ?? options._experiments?.enableLogs;
function LogParameters(options: CapacitorOptions & { enableLogs?: boolean }): CapacitorLoggerOptions | undefined {
// Only Web and Android implements log parameters initialization.
if (shouldEnable && Capacitor.getPlatform() === 'android') {
return { enableLogs: shouldEnable };
if (options.enableLogs && Capacitor.getPlatform() === 'android') {
return { enableLogs: true };
}
return undefined;
}
Expand Down
26 changes: 25 additions & 1 deletion src/options.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { BrowserOptions, makeFetchTransport } from '@sentry/browser';
import type { ClientOptions } from '@sentry/core';
import type { NuxtOptions, VueOptions } from './siblingOptions';

// Direct reference of BrowserTransportOptions is not compatible with strict builds of latest versions of Typescript 5.
type BrowserTransportOptions = Parameters<typeof makeFetchTransport>[0];
Expand Down Expand Up @@ -71,13 +72,36 @@ export interface BaseCapacitorOptions {
* @default 2
*/
appHangTimeoutInterval?: number;


/**
* Only for Vue or Nuxt Client.
* Allows the setup of sibling specific SDK. You are still allowed to set the same parameters
* at the root of Capacitor Options at the cost of lost on JSDocs visibility.
*/
siblingOptions?: {

/**
* Configuration options for the Sentry Vue SDK integration when using Vue.
* These options are passed to the sibling Vue SDK and control Vue-specific features
* such as error handling, component tracing, and props attachment.
*/
vueOptions?: VueOptions;

/**
* Configuration options for the Sentry Nuxt SDK integration when using Nuxt.
* These options are passed to the sibling Nuxt SDK and control Nuxt-specific Vue features
* such as error handling, component tracing, and props attachment.
*/
nuxtClientOptions?: NuxtOptions;
};
}

/**
* Configuration options for the Sentry Capacitor SDK.
*/
export interface CapacitorOptions
extends Omit<BrowserOptions, 'autoSessionTracking' | 'enableLogs'>,
extends Omit<BrowserOptions, '_experiments'>,
BaseCapacitorOptions { }

// eslint-disable-next-line @typescript-eslint/no-empty-interface
Expand Down
26 changes: 15 additions & 11 deletions src/sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,19 @@ import { NATIVE } from './wrapper';
* @param options Options for the SDK
* @param originalInit The init function of the sibling SDK, leave blank to initialize with `@sentry/browser`
*/
export function init<T>(
passedOptions: CapacitorOptions & T,
originalInit: (passedOptions: T & BrowserOptions) => void = browserInit,
export function init(
passedOptions: CapacitorOptions,
originalInit: (passedOptions:BrowserOptions) => void = browserInit,
): void {

const finalOptions = {
enableAutoSessionTracking: true,
enableWatchdogTerminationTracking: true,
enableCaptureFailedRequests: false,
...passedOptions,
};
finalOptions.siblingOptions && delete finalOptions.siblingOptions;

if (finalOptions.enabled === false || NATIVE.platform === 'web') {
Comment on lines 30 to 33

This comment was marked as outdated.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't want

dsn,
siblingOptions: {
vueOptions:{ 
app: app
}
}

to be present, we actually want it to be together with the other options when setting the browser options, like

dsn,
app: app

finalOptions.enableNative = false;
finalOptions.enableNativeNagger = false;
Expand All @@ -38,26 +41,26 @@ export function init<T>(
// const capacitorHub = new Hub(undefined, new CapacitorScope());
// makeMain(capacitorHub);
const defaultIntegrations: false | Integration[] =
passedOptions.defaultIntegrations === undefined
passedOptions.defaultIntegrations === undefined
? getDefaultIntegrations(passedOptions)
: passedOptions.defaultIntegrations;
: passedOptions.defaultIntegrations;

finalOptions.integrations = getIntegrationsToSetup({
integrations: safeFactory(passedOptions.integrations, {
integrations: safeFactory(passedOptions.integrations, {
loggerMessage: 'The integrations threw an error',
}),
defaultIntegrations,
});

if (
finalOptions.enableNative &&
!passedOptions.transport &&
!passedOptions.transport &&
NATIVE.platform !== 'web'
) {
finalOptions.transport = passedOptions.transport || makeNativeTransport;
finalOptions.transport = passedOptions.transport || makeNativeTransport;

finalOptions.transportOptions = {
...(passedOptions.transportOptions ?? {}),
...(passedOptions.transportOptions ?? {}),
bufferSize: DEFAULT_BUFFER_SIZE,
};
}
Expand All @@ -72,18 +75,19 @@ export function init<T>(
}

const browserOptions = {
...passedOptions.siblingOptions?.vueOptions,
...passedOptions.siblingOptions?.nuxtClientOptions,
...finalOptions,
autoSessionTracking:
NATIVE.platform === 'web' && finalOptions.enableAutoSessionTracking,
} as BrowserOptions & T;
} as BrowserOptions;
Comment on lines 75 to +83

This comment was marked as outdated.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BrowserOptions is a common type, and it's used for Angular/React. It's also the same type for Vue/Nuxt with additional parameters.
It indeed extends what is defined by BrowserOptions but it allows the original options to be preserved for the following SDK init.


const mobileOptions = {
...finalOptions,
enableAutoSessionTracking:
NATIVE.platform !== 'web' && finalOptions.enableAutoSessionTracking,
} as CapacitorClientOptions;


sdkInit(browserOptions, mobileOptions, originalInit, passedOptions.transport);
}

Expand Down
3 changes: 3 additions & 0 deletions src/siblingOptions/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@

export type { VueOptions } from './vueOptions';
export type { NuxtOptions } from './nuxtOptions';
3 changes: 3 additions & 0 deletions src/siblingOptions/nuxtOptions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import type { VueOptions } from './vueOptions';

export type NuxtOptions = Omit<VueOptions, 'app'>;
96 changes: 96 additions & 0 deletions src/siblingOptions/vueOptions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import type { BrowserOptions } from '@sentry/browser';
// FILE SYNCED WITH https://github.com/getsentry/sentry-javascript/blob/develop/packages/vue/src/types.ts

// This is not great, but kinda necessary to make it work with Vue@2 and Vue@3 at the same time.
export interface Vue {
config: {
errorHandler?: any;
warnHandler?: any;
silent?: boolean;
};
mixin: (mixins: Partial<Record<Hook, any>>) => void;
}

export type ViewModel = {
_isVue?: boolean;
__isVue?: boolean;
$root: ViewModel;
$parent?: ViewModel;
$props: { [key: string]: any };
$options?: {
name?: string;
propsData?: { [key: string]: any };
_componentTag?: string;
__file?: string;
__name?: string;
};
};

export interface VueOptions {
/** Vue constructor to be used inside the integration (as imported by `import Vue from 'vue'` in Vue2) */
Vue?: Vue;

/**
* Vue app instance(s) to be used inside the integration (as generated by `createApp` in Vue3).
*/
app?: Vue | Vue[];

/**
* When set to `false`, Sentry will suppress reporting of all props data
* from your Vue components for privacy concerns.
*/
attachProps: boolean;

/**
* By default, Sentry attaches an error handler to capture exceptions and report them to Sentry.
* When `attachErrorHandler` is set to `false`, automatic error reporting is disabled.
*
* Usually, this option should stay enabled, unless you want to set up Sentry error reporting yourself.
* For example, the Sentry Nuxt SDK does not attach an error handler as it's using the error hooks provided by Nuxt.
*
* @default true
Comment on lines +40 to +52

This comment was marked as outdated.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to keep it as is since it's an exact copy of Vue options.

*/
attachErrorHandler: boolean;

/** {@link TracingOptions} */
tracingOptions?: Partial<TracingOptions>;
}

export type Options = BrowserOptions & VueOptions;

/** Vue specific configuration for Tracing Integration */
export interface TracingOptions {
/**
* Decides whether to track components by hooking into its lifecycle methods.
* Can be either set to `boolean` to enable/disable tracking for all of them.
* Or to an array of specific component names (case-sensitive).
*/
trackComponents: boolean | string[];

/** How long to wait until the tracked root activity is marked as finished and sent of to Sentry */
timeout: number;

/**
* List of hooks to keep track of during component lifecycle.
* Available hooks: 'activate' | 'create' | 'destroy' | 'mount' | 'unmount' | 'update'
* Based on https://vuejs.org/v2/api/#Options-Lifecycle-Hooks
*/
hooks: Operation[];
}

export type Hook =
| 'activated'
| 'beforeCreate'
| 'beforeDestroy'
| 'beforeUnmount'
| 'beforeMount'
| 'beforeUpdate'
| 'created'
| 'deactivated'
| 'destroyed'
| 'unmounted'
| 'mounted'
| 'updated';

export type Operation = 'activate' | 'create' | 'destroy' | 'mount' | 'update' | 'unmount';
11 changes: 5 additions & 6 deletions test/nativeOptions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,12 +138,11 @@ describe('nativeOptions', () => {

test('Set logger on Android', () => {
mockGetPlatform.mockReturnValue('android');
const filteredOptions: CapacitorOptions = {
_experiments: { enableLogs : true}
const filteredOptions: CapacitorOptions & { enableLogs?: boolean } = {
enableLogs: true
};
const expectedOptions = {
// @ts-ignore
enableLogs : true
enableLogs: true
};

const nativeOptions = FilterNativeOptions(filteredOptions);
Expand All @@ -154,8 +153,8 @@ describe('nativeOptions', () => {

test('Ignore logger on iOS', () => {
mockGetPlatform.mockReturnValue('ios');
const filteredOptions: CapacitorOptions = {
_experiments: { enableLogs : true}
const filteredOptions: CapacitorOptions & { enableLogs?: boolean } = {
enableLogs: true
};

const nativeOptions = FilterNativeOptions(filteredOptions);
Expand Down
Loading
Loading