npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

bugsplat-ng

v17.0.0

Published

BugSplat error reporting for Angular

Downloads

60

Readme

bugsplat-github-banner-basic-outline

BugSplat

Crash and error reporting built for busy developers.

👋 Introduction

BugSplat supports the collection of errors in Angular applications. The bugsplat-ng npm package implements Angular’s ErrorHandler interface in order to post errors to BugSplat, where they can be tracked and managed. Adding BugSplat to your Angular application is extremely easy. Before getting started, please complete the following tasks:

  • Sign up for BugSplat
  • Complete the welcome workflow and take note of your BugSplat database
  • Check out the live demo of BugSplat’s Angular error reporting

🧑‍🏫 Sample

This repository includes a sample my-angular-crasher application that has been pre-configured with BugSplat. Before you try the sample, you'll need to create an OAuth2 Client ID & Client Secret pair that corresponds to your BugSplat database as shown here.

Once you've generated OAuth2 credentials, create a file with the name .env at the root of the repository and populate it with the correct values substituted for {{database}}, {{clientId}} and {{clientSecret}}:

BUGSPLAT_DATABASE={{database}}
SYMBOL_UPLOAD_CLIENT_ID={{clientId}}
SYMBOL_UPLOAD_CLIENT_SECRET={{clientSecret}}

To test the sample, perform the following steps:

  1. git clone https://github.com/BugSplat-Git/bugsplat-ng
  2. cd bugsplat-ng && npm i
  3. npm start

The npm start command will build the sample application and upload source maps to BugSplat so that the JavaScript call stack can be mapped back to TypeScript. Once the build has completed, the source maps will be uploaded and http-server will serve the app.

Navigate to the url displayed in the console by http-server (usually localhost:8080). Click any button in the sample app to generate an error report. A link to the error report should display in the app shortly after clicking a button. Click the link to the error report and when prompted to log into BugSplat.

If everything worked correctly you should see information about your error as well as a TypeScript stack trace.

⚙️ Integration

To collect errors and crashes in your Angular application, run the following command in the terminal or cmd at the root of your project to install bugsplat-ng:

npm i bugsplat-ng --save

Add values for your BugSplat database, application, and version to your application's environment files. Be sure to substitute the same value for {{database}} as the value you used for your BUGSPLAT_DATABASE env variable:

environment.prod.ts

const packageJson = require('../../package.json');
export const environment = {
  production: true,
  bugsplat: {
    database: '{{database}}',
    application: packageJson.name,
    version: packageJson.version
  }
};

Add an import for BugSplatModule to your AppModule:

app.module.ts

import { BugSplatModule } from 'bugsplat-ng';

Add a call BugSplatModule.initializeApp in your AppModule's imports array, passing it your database, application, and version:

app.module.ts

...
@NgModule({
  imports: [
    BugSplatModule.initializeApp(environment.bugsplat)
  ],
  ...
})

Throw a new error in your application to test the bugsplat-ng integration:

app.component.ts

throw new Error("foobar!");

Navigate to the Crashes page in BugSplat, and you should see a new crash report for the application you just configured. Click the link in the ID column to see details about your crash on the Crash page:

🧰 Extended Integration

You can post additional information by creating a service that implements ErrorHandler. In the handlerError method, make a call to BugSplat.post passing it the error and an optional options object:

my-angular-error-handler.ts

import { ErrorHandler, Injectable } from '@angular/core';
import { BugSplat } from 'bugsplat-ng';

@Injectable()
export class MyAngularErrorHandler implements ErrorHandler {

    constructor(public bugsplat: BugSplat) { }
    
    async handleError(error: Error): Promise<void> {
        return this.bugsplat.post(error, {
            description: 'New description from MyAngularErrorHandler.ts'
        });
    }
}

BugSplat provides the following properties and methods that allow you to customize its functionality:

bugsplat.ts

BugSplat.description: string; // Additional info about your crash that gets reset after every post
BugSplat.email: string; // The email of your user 
BugSplat.key: string; // A unique identifier for your application
BugSplat.user: string; // The name or id of your user
BugSplat.files: Array<file>; // A list of files to be uploaded at post time
BugSplat.getObservable(): Observable<BugSplatPostEvent>; // Observable that emits BugSplat crash post events results in your components.
async BugSplat.post(error): Promise<void>; // Post an Error object to BugSplat manually from within a try/catch

In your AppModule's NgModule definition, add a provider for your new ErrorHandler:

app.module.ts

import { ErrorHandler, NgModule } from '@angular/core';

@NgModule({
  providers: [
    {
      provide: ErrorHandler,
      useClass: MyAngularErrorHandler
    }
  ]
  ...
})

You can also configure BugSplat's logging preferences and provide your own logging implementation. Create a provider for BugSplatLogger with useValue set to a new instance of BugSplatLogger. Pass one of the BugSplatLogLevel options as the first parameter to BugSplatLogger. You can provide an instance of your own custom logger as the second parameter granted it has an error, warn, info, and log methods. If no custom logger is provided, the console will be used:

app.module.ts

import { ErrorHandler, NgModule } from '@angular/core';
import { BugSplatLogger, BugSplatLogLevel, BugSplatModule } from 'bugsplat-ng';

@NgModule({
  providers: [
    {
      provide: ErrorHandler,
      useClass: BugSplatErrorHandler
    },
    {
      provide: BugSplatLogger,
      useValue: new BugSplatLogger(BugSplatLogLevel.Log)
    }
  ],
  ...
})

🗺 Source Maps

BugSplat supports unwinding uglified and minified JavaScript stack traces via source maps. To upload source maps to BugSplat during your build, install @bugsplat/symbol-upload.

npm i -D @bugsplat/symbol-upload

Configure your angular.json file to output source maps. We suggest enabling source maps for both your application code and any vendor chunks generated by Angular.

{
  "projects": {
    "main": {
      "architect": {
        "build": {
          "options": {
            "sourceMap": {
              "scripts": true,
              "styles": true,
              "vendor": true
            },
          },
        }
      }
    }
  }
}

Add SYMBOL_UPLOAD_CLIENT_ID and SYMBOL_UPLOAD_CLIENT_SECRET environment variables for the BugSplat user that you will use to upload symbols. You can create these values as system environment variables or use dotenv.

SYMBOL_UPLOAD_CLIENT_ID={{clientId}}
SYMBOL_UPLOAD_PASSWORD={{clientSecret}}

Create a script for uploading source maps.

const { OAuthClientCredentialsClient, SymbolsApiClient } = require('@bugsplat/symbol-upload');
const fs = require('fs');
const path = require('path');
const packageJson = require('../package.json');
require('dotenv').config();

(async () => {
    const clientId = process.env['SYMBOL_UPLOAD_CLIENT_ID'];
    if (!clientId) {
        throw new Error('Please set SYMBOL_UPLOAD_CLIENT_ID in .env file');
    }

    const clientSecret = process.env['SYMBOL_UPLOAD_CLIENT_SECRET'];
    if (!clientSecret) {
        throw new Error('Please set SYMBOL_UPLOAD_CLIENT_SECRET in .env file');
    }

    const database = packageJson.database;
    const application = packageJson.name;
    const version = process.argv[2] === 'dev' ? `${packageJson.version}-dev` : packageJson.version;

    const buildDirectory = `./dist/${application}`;

    if (!fs.existsSync(buildDirectory)) {
        throw new Error(`Build directory ${buildDirectory} does not exist!`);
    }

    const files = fs.readdirSync(buildDirectory)
        .filter((fileName: string) => fileName.endsWith('.js.map'))
        .map((fileName: string) => {
            const filePath = `${buildDirectory}/${fileName}`;
            const stat = fs.statSync(filePath);
            const name = path.basename(filePath);
            const size = stat.size;
            return {
                name,
                size,
                file: fs.createReadStream(filePath)
            };
        });

    if (!files.length) {
        throw new Error(`No source map files found in ${buildDirectory}!`);
    }

    const bugsplat = await OAuthClientCredentialsClient.createAuthenticatedClient(clientId, clientSecret);
    const symbolsApiClient = new SymbolsApiClient(bugsplat);
    await symbolsApiClient.deleteSymbols(
        database,
        application,
        version
    );
    await symbolsApiClient.postSymbols(
        database,
        application,
        version,
        files
    );
    console.log(`Source maps uploaded to BugSplat ${database}-${application}-${version} successfully!`);
})().catch(error => {
    console.error(error);
    process.exit(1);
});

Add postbuild and symbols scripts to your package.json.

{
  "scripts": {
    "postbuild": "npm run symbols",
    "symbols": "ts-node ./scripts/symbols.ts"
  }
}

For best results, please upload source maps for every released version of your application.

🧑‍💻 Contributing

BugSplat loves open-source software! If you have suggestions on how we can improve this integration, please reach out to [email protected], create an issue in our GitHub repo or send us a pull request.

With ❤️,

The BugSplat Team