Code Monkey home page Code Monkey logo

bugsplat-ng's Introduction

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. Get started by cloning the repository and navigating to the root of the project:

git clone https://github.com/BugSplat-Git/bugsplat-ng
cd bugsplat-ng

Before you can run the app, you'll need to create an OAuth2 Client ID & Client Secret pair that corresponds to your BugSplat database as shown here. Please also take note of the BugSplat database that this OAuth2 Client ID & Client Secret pair corresponds to.

First, add a database property in your package.json that corresponds to your BugSplat database:

{
  "database": "your_bugsplat_database"
}

Next, create a dotenv file with the name .env at the root of the repository and populate it with the correct values substituted for your-client-id and your-client-secret:

SYMBOL_UPLOAD_CLIENT_ID=your-client-id
SYMBOL_UPLOAD_CLIENT_SECRET=your-client-secret

To start the sample app, run npm start in the root of the repository.

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 a database property in your package.json that corresponds to your BugSplat database:

{
  "database": "your_bugsplat_database"
}

Add values for your BugSplat database, application, and version to your application's environment files.

environment.prod.ts

const packageJson = require('../../package.json');
export const environment = {
  production: true,
  bugsplat: {
    database: packageJson.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:

Crashes page 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=your-client-id
SYMBOL_UPLOAD_PASSWORD=your-client-secret

Add a script to package.json that reads a .env file and calls symbol-upload to upload source maps after your production build. Replace my-angular-crasher with the name of your Angular project.

{
  "scripts": {
    "postbuild": "node -r dotenv/config ./node_modules/@bugsplat/symbol-upload/dist/bin/index.js -d ./dist/my-angular-crasher/browser"
  }
}

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](https://github.com/BugSplat-Git/bugsplat-ng/issues) in our [GitHub repo](https://github.com/BugSplat-Git/bugsplat-ng) or send us a [pull request](https://github.com/BugSplat-Git/bugsplat-ng/pulls). 

With ❀️,

The BugSplat Team

bugsplat-ng's People

Contributors

bobbyg603 avatar dependabot[bot] avatar semantic-release-bot avatar zmrl010 avatar zoolouie avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

bugsplat-ng's Issues

Acceptance tests can only be run against Octomore

Octomore is a BugSplat dev server that is only on part-time. We need to figure out what the CORS issue is on the production server so that we can Fred as the testDatabase in the acceptance tests.

Tsconfig should target ES5

@terodox suggested that we should target ES5. This was the original intention but there were several TSC errors related to angular when we did this originally and the only fix we had was to go to ES6. We should revisit this.

Should be able to override logger

This seems to have broken when we improved the initialization UX. We need to make the dependency optional and not provide it in the module so it can be overridden by the consumer.

Improve Sample

Here are some things we'd like to improve in the sample:

  • Add BugSplat background asset to page
  • Add a blurb with a link to our docs

Welcome to my-angular-crasher! This is a sample application that demonstrates BugSplat error reporting for Angular applications built with JavaScript or TypeScript.

  • Add buttons that demonstrate different types of errors. Each button should trigger the same type of error in the BugSplat sample. Each button should post a crash report and display update the link to the crash in BugSplat.
    • Not a function
    • Uri Errror
    • Syntax Error
    • Range Error
    • Throw new Error('BugSplat rocks!')
  • Style the link to the crash so that it fits the updated design
  • Anything else that would make the page look nice (resize the header, change font sizes, font colors, etc)

Here are some assets that should help in this endeavor.

Error message should be posted to BugSplat

Not sure what happened here, but we got the following POST

------WebKitFormBoundaryb8F55GftGYv8ldPA
Content-Disposition: form-data; name="appName"

bugsplat-web-app
------WebKitFormBoundaryb8F55GftGYv8ldPA
Content-Disposition: form-data; name="appVersion"

1.7.6
------WebKitFormBoundaryb8F55GftGYv8ldPA
Content-Disposition: form-data; name="database"

BugSplatWebApp
------WebKitFormBoundaryb8F55GftGYv8ldPA
Content-Disposition: form-data; name="callstack"

transform@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:569286
https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:444263
ig@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:452646
https://app.bugsplat.com/v2/15.3c5cb9b805b8657f4a2b.js:1:21118
km@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:441373
Bm@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:448181
Vm@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:447844
km@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:441259
Bm@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:448181
Vm@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:447844
km@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:441259
Bm@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:448181
Vm@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:447844
km@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:441259
Bm@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:448181
Lm@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:447579
km@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:441381
Bm@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:448181
Vm@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:447844
km@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:441259
Bm@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:448181
Vm@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:447844
km@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:441259
Bm@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:448181
Lm@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:447579
km@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:441381
Bm@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:448181
Vm@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:447844
km@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:441259
Bm@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:448181
Vm@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:447844
km@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:441259
Bm@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:448181
Vm@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:447844
km@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:441259
Bm@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:448181
Lm@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:447579
km@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:441381
Bm@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:448181
Lm@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:447579
km@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:441381
Bm@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:448181
Lm@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:447579
km@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:441381
Bm@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:448181
Lm@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:447579
km@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:441381
Bm@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:448181
Vm@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:447844
km@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:441259
Bm@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:448181
Lm@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:447579
km@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:441381
Bm@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:448181
Vm@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:447844
km@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:441259
Bm@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:448181
Lm@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:447579
km@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:441381
detectChanges@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:422646
forEach@[native code]
tick@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:379030
https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:377381
onInvoke@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:368561
run@https://app.bugsplat.com/v2/polyfills.0c307bbaf6501dd00d85.js:1:3601
next@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:377363
https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:333941
__tryOrUnsub@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:499735
next@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:498888
_next@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:497924
next@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:497596
next@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:575231
emit@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:333722
Mp@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:369732
onHasTask@https://app.bugsplat.com/v2/main.7c5a6225726d9f01f727.js:1:368700
hasTask@https://app.bugsplat.com/v2/polyfills.0c307bbaf6501dd00d85.js:1:9402
_updateTaskCount@https://app.bugsplat.com/v2/polyfills.0c307bbaf6501dd00d85.js:1:9656
_updateTaskCount@https://app.bugsplat.com/v2/polyfills.0c307bbaf6501dd00d85.js:1:5854
runTask@https://app.bugsplat.com/v2/polyfills.0c307bbaf6501dd00d85.js:1:4472
g@https://app.bugsplat.com/v2/polyfills.0c307bbaf6501dd00d85.js:1:11350
invokeTask@https://app.bugsplat.com/v2/polyfills.0c307bbaf6501dd00d85.js:1:10189
y@https://app.bugsplat.com/v2/polyfills.0c307bbaf6501dd00d85.js:1:23611
b@https://app.bugsplat.com/v2/polyfills.0c307bbaf6501dd00d85.js:1:23909
------WebKitFormBoundaryb8F55GftGYv8ldPA
Content-Disposition: form-data; name="appKey"


------WebKitFormBoundaryb8F55GftGYv8ldPA
Content-Disposition: form-data; name="user"


------WebKitFormBoundaryb8F55GftGYv8ldPA
Content-Disposition: form-data; name="email"

[email protected]
------WebKitFormBoundaryb8F55GftGYv8ldPA
Content-Disposition: form-data; name="description"

null
------WebKitFormBoundaryb8F55GftGYv8ldPA--

But the following message appeared in the console but wasn't sent to BugSplat:

Error: InvalidPipeArgument: 'Unable to convert "2019-04-26 02:19:54" into a date' for pipe 't'

No example of how to create/attach a log file

There is an example in my-angular-4-crasher regarding how to create and attach an image, however we should make a convenient factory method that can create/attach a log file for the consumer.

Update docs

The consumer no longer needs to define providers, let's update the docs to reflect the most recent changes.

Update to Angular 14

We should probably start matching our major versions to the Angular major versions as well...

Improve sample usability

Feedback from Dave:

  • Move Crashes created to bottom of window in scrolling text area (with crash preview?)
  • Change 'Errors' to 'Click an Error Type below to Generate a Crash Report'

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.