npm package: @okode/ngx-sentry
Description: Angular library to setup and configure Sentry projects easily on your applications.
Latest version: 1.1.2

# Sentry for Angular

Angular library to setup and configure Sentry projects easily on your applications.

# Install

```bash
npm i @okode/ngx-sentry
```

# Usage

## Configure the Sentry Provider

### **All-in-one configuration**:

- `provideSentry`: Initializes on bootstrap an configures Sentry with the following default features => [`withDefaultHttpInterceptor`](#withdefaulthttperrorinterceptor) y [`withDefaultErrorHandler`](#withdefaulterrorhandler)

```typescript
import { provideSentry } from '@okode/ngx-sentry';

export const appConfig: ApplicationConfig = {
  providers: [
    ...
    provideSentry({
      dsn: 'YOUR_APP_DSN',
      enabled: true,
      release: '0.0.0',
      env: 'YOUR_APP_ENV', // <- dev, pre, pro
    }),
  ],
  ...
};
```

### **Fine-grained configuration by features**:

- `provideSentryWithFeatures`: allow to configure Sentry with modular features and your own custom features. ( API REFERENCE -> [SentryFeatures](#sentry-features))

```typescript
import { provideSentryWithFeatures, withConfig, withDefaultErrorHandler } from '@okode/ngx-sentry';

export const appConfig: ApplicationConfig = {
  providers: [
    ...
    provideSentryWithFeatures(
        withConfig({
        dsn: 'YOUR_APP_DSN',
        enabled: true,
        release: '0.0.0',
        env: 'YOUR_APP_ENV', // <- dev, pre, pro
      }),
      withDefaultErrorHandler(),
      // Add any other custom feature here
    ),
  ],
  ...
};
```

## Manual initialization

The default `provideSentry()` function automatically initializes Sentry on bootstrap. If you want to init Sentry on some other point, you'll have to use `provideSentryWithFeatures()` function and avoid using `withConfig()`.

```typescript
import { provideSentryWithFeatures, withDefaultHttpErrorInterceptor, withDefaultErrorHandler } from '@okode/ngx-sentry';

export const appConfig: ApplicationConfig = {
  providers: [
    ...
    provideSentryWithFeatures(
      withDefaultHttpErrorInterceptor(),
      withDefaultErrorHandler()
    ),
    ...
  ],
...
};
```

Now, in some other point on your app, you can `init()` the `SentryErrorReporterService`.

```typescript
// some other place

import { SentryErrorReporterService } from '@okode/ngx-sentry';
import { version } from './package.json';

export class OtherPlaceService {

constructor(private sentryService: SentryErrorReporterService) {
      this.sentryService.init({
      dsn: 'YOUR_APP_DSN',
      enabled: true,
      release: '0.0.0',
      env: 'YOUR_APP_ENV', // <- dev, pre, pro
      release: version,
    });
  }
...
}
```

## Send a custom error

Send a custom error whenever you need.

```typescript
import { SentryErrorReporterService } from '@okode/ngx-sentry';

export class OtherPlaceService {
  constructor(private sentryService: SentryErrorReporterService) {}

  sendCustomErrorWithError(): void {
    this.sentryService.sendCustomError('MY_ERROR', new Error('PoC Error'));
  }
}
```

# Integration with microfrontends - Monitoring microfrontend errors

> Supported since version `0.18.0+`.

If a Javascript error happens in a microfrontend feature, this is registered as an application error because this error cannot be identified as external error by default. In addition, Sentry doesn't show any kind of useful information about this error because it doesn't belong to the application project, the trace is minified because there are no source maps, etc.

This library is able to identify and redirect errors that reference its own Sentry project without an extra effort.  So, what we have to do is to customize the microfrontend build and to add some metadata that allows application/library to identify this errors as microfrontend errors and redirect them to its own Sentry project.

> Remember uploading microfrontend source maps to its Sentry project after it is built, otherwise you will still see the trace minified.

[Official docs](https://docs.sentry.io/platforms/javascript/configuration/micro-frontend-support/)

# API

- [API](#api)
  - [Sentry Provider Functions](#sentry-provider-functions)
    - [provideSentry(...)](#providesentry)
    - [provideSentryWithFeatures(...)](#providesentrywithfeatures)
  - [Sentry Features](#sentry-features)
    - [withConfig(...)](#withconfig)
    - [withDefaultHttpErrorInterceptor()](#withdefaulthttperrorinterceptor)
    - [withDefaultErrorHandler()](#withdefaulterrorhandler)
    - [makeSentryFeature(...)](#makesentryfeature)
  - [SentryErrorReporterService](#sentryerrorreporterservice)
    - [init(...)](#init)
    - [sendError(...)](#senderror)
    - [sendServerError(...)](#sendservererror)
    - [sendCustomError(...)](#sendcustomerror)
    - [setUserScope(...)](#setuserscope)
  - [SentryReportErrorHttpInterceptor](#sentryreporterrorhttpinterceptor)
    - [intercept(...)](#intercept)
  - [SentryErrorHandler](#sentryerrorhandler)
    - [handleError(...)](#handleerror)
  - [Models](#models)
    - [Sentry Config](#sentry-config)
    - [User](#user)
    - [SentryFeature](#sentryfeature)
    - [SentryFeatureKind](#sentryfeaturekind)
  - [FAQ](#faw)
    - [How to customize any error tracked in Sentry?](#how-to-customize-any-error-tracked-in-sentry)


## Sentry Provider Functions

### provideSentry(...)

```typescript
provideSentry(config: SentryConfigResolver) => EnvironmentProviders
```

Sets a Sentry default setup provider.

| Param  |         Type         |
| :----: | :------------------: |
| config | SentryConfigResolver |

---

### provideSentryWithFeatures(...)

```typescript
 provideSentryWithFeatures(...features: SentryFeature<SentryFeatureKind>[]) => EnvironmentProviders
```

Sets a Sentry setup provider with additional features.

|  Param   |                Type                |
| :------: | :--------------------------------: |
| features | SentryFeature<SentryFeatureKind>[] |

---

## Sentry Features

### withConfig(...)

```typescript
withConfig(config: SentryConfigResolver) => SentryFeature<SentryFeatureKind.CONFIG>
```

Sets a custom SentryConfigRevolver and initializes Sentry.

| Param  |         Type         |
| :----: | :------------------: |
| config | SentryConfigResolver |

---

### withDefaultHttpErrorInterceptor()

```typescript
withDefaultHttpErrorInterceptor() => SentryFeature<SentryFeatureKind.DEFAULT_HTTP_ERROR_INTERCEPTOR>
```

Provides the default HTTPErrorInterceptor service.

---

### withDefaultErrorHandler()

```typescript
withDefaultErrorHandler() => SentryFeature<SentryFeatureKind.DEFAULT_ERROR_HANDLER>
```

Provides the default ErrorHandler service.

### makeSentryFeature(...)

```typescript
makeSentryFeature<KindT extends SentryFeatureKind>(  kind: KindT,  providers: Provider[]) =>SentryFeature<KindT>
```

Creates a custom SentryFeature.

|   Param   |    Type    |
| :-------: | :--------: |
|   kind    |   KindT    |
| providers | Provider[] |

## SentryErrorReporterService

Sentry service that communication with Sentry.

### init(...)

```typescript
init(config: SentryConfig) => void
```

Initializes Sentry Service.

| Param  |     Type     |
| :----: | :----------: |
| config | SentryConfig |

---

### sendError(...)

```typescript
sendError(error: unknown) => void
```

Sends Error.

| Param |  Type   |
| :---: | :-----: |
| error | unknown |

---

### sendServerError(...)

```typescript
sendServerError(error: HttpErrorResponse, req: HttpRequest<unknown>) => void
```

Sends Server Error.

| Param |         Type         |
| :---: | :------------------: |
| error |  HttpErrorResponse   |
|  req  | HttpRequest<unknown> |

---

### sendCustomError(...)

```typescript
sendCustomError(errorCode: string, error?: unknown, level: 'debug' | 'warning' = 'debug') => void
```

Sends Custom Error.

|   Param   |         Type         |
| :-------: | :------------------: |
| errorCode |        string        |
|   error   |       unknown        |
|   level   | 'debug' or 'warning' |

---

### setUserScope(...)

```typescript
setUserScope(sentryUserScope: User) => void
```

Sets a User scope.

|      Param      | Type |
| :-------------: | :--: |
| sentryUserScope | User |

## SentryReportErrorHttpInterceptor

### intercept(...)

```typescript
intercept(request: HttpRequest<unknown>, next: HttpHandler) => Observable<HttpEvent<unknown>>
```

Intercepts HTTP Errors.

|  Param  |         Type         |
| :-----: | :------------------: |
| request | HttpRequest<unknown> |
|  next   |     HttpHandler      |

## SentryErrorHandler

### handleError(...)

```typescript
handleError(error: unknow) => void
```

Handle thrown errors.

| Param |  Type   |
| :---: | :-----: |
| error | unknown |

## Models

### Sentry Config

|       Param        |                                       Type                                        |
| :----------------: | :-------------------------------------------------------------------------------: |
|        dsn         |                                      string                                       |
|      enabled       |                                      boolean                                      |
|        env         |                                      string                                       |
|      release       |                                      string                                       |
|        dist        |                                      string                                       |
|      denyUrls      |                               (RegExp \| string)[]                                |
|       debug        |                                      boolean                                      |
|     logErrors      |                                      boolean                                      |
|  tracesSampleRate  |                                      number                                       |
|    ignoreErrors    |                               (RegExp \| string)[]                                |
|     beforeSend     | (event:ErrorEvent, hint:EventHint) => PromiseLike<Event \| null> \| Event \| null |
| integrationsConfig |             { browserTracing: { tracePropagationTargets?:string[];} }             |

**Default denyUrls**

```js
  /extensions\//i,
  /^chrome:\/\//i,
  /safari-extension:/i,
  /ruxitagentjs/i,
  /googletagmanager/i,
  /pagead\/js/i,
  /\/(gtm|ga|analytics)\.js/i,
  /facebook\.com/i,
  /connect\.facebook\.net/i,
  /ubembed\.com/i,
  /cdn\.cookielaw\.org/i,
  /onetrust\.org/i,
  /googleapis\.com/i,
  /chatasistencia\/auraFW\//i,
  /embeddedService\/liveAgentStateChat\//i,
  /force\.com/i,
  /salesforceliveagent\.com/i,

```
---

### User

|     Param     |       Type       |
| :-----------: | :--------------: |
| [key: string] |       any        |
|      id       | string \| number |
|  ip_address   |      string      |
|     email     |      string      |
|   username    |      string      |
|    segment    |      string      |

---

### SentryFeature

|   Param    |    Type    |
| :--------: | :--------: |
|   ekind    |   KindT    |
| eproviders | Provider[] |

---

### SentryFeatureKind

|              ENUM              |
| :----------------------------: |
|             CONFIG             |
| DEFAULT_HTTP_ERROR_INTERCEPTOR |
|     DEFAULT_ERROR_HANDLER      |

## FAQ

### How to customize any error tracked in Sentry?

In the Sentry library, most use cases for error monitoring are covered, but it's always possible that additional aspects need to be implemented for specific project needs. For this reason, the Sentry library is extensible and can be customized.

To achieve this, you need to create a new service in your application, for example, sentry-reporter-service-ext.service.ts. This service should extend the class you want to modify.

In the providers of your application, you need to indicate that the new service created will replace the Sentry service from the library as follows:

```typescript
{ provide: SentryErrorReporterService, useExisting: SentryErrorReporterServiceExt }
```

To customize error monitoring according to your specific requirements or to add new features, you'll need to use the @override annotation to replace or extend the functionality of the existing functions.

```typescript
export class SentryErrorReporterServiceExt extends SentryErrorReporterService {

  constructor(
    @Inject(INJECTOR) injector: Injector,
    @Inject(PLATFORM_ID) platformId: string,
    @Inject(DOCUMENT) document: Document,
  ) {
    super(injector, platformId, document);
  }

  override sendError(error: unknown) {
    // [Your custom implementation]
  }
}
```