bugsee 1.0.3

  • README.md
  • CHANGELOG.md
  • Example
  • Installing
  • Versions
  • new50

Bugsee for flutter

Bugsee is a mobile SDK that adds crucial information to your bug and crash reports. Bugsee reports include video of user actions, network traffic, console logs and many other important traces from your app. Now you know what exactly led to the unexpected behavior.

Sign up for a service at https://www.bugsee.com.

Installation

Install Bugsee plugin into your dart project by adding it to dependecies in your pubspec.yaml

dependencies:
  bugsee: any

Import Bugsee in every file you plan to call Bugsee API from:

import 'package:bugsee/bugsee.dart';

Launching

Bugsee SDK has to be launched within the native part of your application

iOS

Locate your ios/Runner/AppDelegate.m and add the following:

#import "Bugsee/Bugsee.h"

/// ...

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  [GeneratedPluginRegistrant registerWithRegistry:self];

  [Bugsee launchWithToken:@"<YOUR APP TOKEN>"];
  
  // Override point for customization after application launch.
  return [super application:application didFinishLaunchingWithOptions:launchOptions];
}

Refer to official native iOS documentation for additional launch options.

Android

Add native Bugsee SDK to your build.gradle:

dependencies {
    implementation 'com.bugsee:bugsee-android:+'
}

If you don't have it already, create your own class for main application and make sure you extend FlutterApplication when doing so. Launch the Bigsee SDK from there:

import com.bugsee.library.Bugsee;
import java.util.HashMap;
import io.flutter.app.FlutterApplication;

public class MainApplication extends FlutterApplication {
    @Override
    public void onCreate() {
        super.onCreate();
        HashMap<String, Object> options = new HashMap<>();

        // Regular doesn't capture anything in Flutter for now
        options.put(Bugsee.Option.ExtendedVideoMode, true);
        Bugsee.launch(this, "<YOUR APP TOKEN>", options);
    }
}

Modify the manifest to point to this Application:

    <application
        android:name="com.acme.app.MainApplication"
        ...

Refer to official native Android documentation for additional launch options.

Custom data

Events

Events are identified by a string and can have an optional dictionary of parameters that will be stored and passed along with the report.

// Without any additional parameters
Bugsee.event(name: 'payment_processed');

// ... or with additional custom parameters
Bugsee.event(name: 'payment_processed', parameters: <String, dynamic>{
                'amount': 125,
                'currency': 'USD'});

Traces

Traces may be useful when you want to trace how a specific variable or state changes over time right before the problem happens.

// Manually set value of 15 to property named "credit_balance"
// any time it changes
Bugsee.trace(name: 'credit_balance', value: 15);    

Manual reporting

You can register non fatal exceptions using the following method:

try {
  some_code_that_throws();
} catch (ex, st) {
  await Bugsee.logException(exception: ex, handled: true, stackTrace: st);
}

Auto exception handling

Create the following method in your code:

Future<Null> _reportError(dynamic error, dynamic stackTrace) async {
  print('Caught error: $error');

  await Bugsee.logException(
    exception: error,
    handled: false,
    stackTrace: stackTrace,
  );
}

Hook the method to execute on Flutter errors:

// This captures errors reported by the Flutter framework.
FlutterError.onError = (FlutterErrorDetails details) async {
  // In production mode report to the application zone to report to Bugsee.
  Zone.current.handleUncaughtError(details.exception, details.stack);
};

Wrap your application to run in a Zone, which will catch most of the unhandled errors automatically:

// This creates a [Zone] that contains the Flutter application and stablishes
// an error handler that captures errors and reports them.
//
// Using a zone makes sure that as many errors as possible are captured,
// including those thrown from [Timer]s, microtasks, I/O, and those forwarded
// from the `FlutterError` handler.
//
// More about zones:
//
// - https://api.dartlang.org/stable/1.24.2/dart-async/Zone-class.html
// - https://www.dartlang.org/articles/libraries/zones
runZoned<Future<Null>>(() async {
  runApp(new CrashyApp());
  }, onError: (error, stackTrace) async {
  await _reportError(error, stackTrace);
});

Privacy

For privacy reasons rectangular regions in the video may be concealed by using the following methods:

Rect hiddenRect = const Offset(50.0, 50.0) &
                      const Size(100.0, 100.0);

// Hide region
Bugsee.addSecureRect(rect: hiddenRect);

// Unhide region
Bugsee.removeSecureRect(rect: hiddenRect);

// Unhide everything
Bugsee.removeAllSecureRects();

Bugsee can be further customized. For a complete SDK documentation covering additional options and API's visit https://docs.bugsee.com/sdk/flutter

[0.0.1] - TODO: Add release date.

  • TODO: Describe initial release.

example/lib/main.dart

// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

/// This is a sample Flutter app that demonstrates how to catch various kinds
/// of errors in Flutter apps and report them to Bugsee.
/// 
/// Explanations are provided in the inline comments in the code below.
library crashy;

import 'dart:async';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:http/http.dart' as http;


// This imports the Bugsee plugin
import 'package:bugsee/bugsee.dart';

/// Whether the VM is running in debug mode.
/// 
/// This is useful to decide whether a report should be sent to Bugsee. Usually
/// reports from dev mode are not very useful, as these happen on developers'
/// workspaces rather than on users' devices in production.
bool get isInDebugMode {
  bool inDebugMode = false;
//  assert(inDebugMode = true);
  return inDebugMode;
}

// Reports [error] along with its [stackTrace] to Bugsee
Future<Null> _reportError(dynamic error, dynamic stackTrace) async {
  print('Caught error: $error');

  // Errors thrown in development mode are unlikely to be interesting. You can
  // check if you are running in dev mode using an assertion and omit sending
  // the report.
  if (isInDebugMode) {
    print(stackTrace);
    print('In dev mode. Not sending report to Bugsee.');
    return;
  }

  await Bugsee.logException(
    exception: error,
    handled: false,
    stackTrace: stackTrace,
  );
}

Future<Null> main() async {
  // This captures errors reported by the Flutter framework.
  FlutterError.onError = (FlutterErrorDetails details) async {
    if (isInDebugMode) {
      // In development mode simply print to console.
      FlutterError.dumpErrorToConsole(details);
    } else {
      // In production mode report to the application zone to report to Bugsee.
      Zone.current.handleUncaughtError(details.exception, details.stack);
    }
  };

  // This creates a [Zone] that contains the Flutter application and stablishes
  // an error handler that captures errors and reports them.
  //
  // Using a zone makes sure that as many errors as possible are captured,
  // including those thrown from [Timer]s, microtasks, I/O, and those forwarded
  // from the `FlutterError` handler.
  //
  // More about zones:
  //
  // - https://api.dartlang.org/stable/1.24.2/dart-async/Zone-class.html
  // - https://www.dartlang.org/articles/libraries/zones
  runZoned<Future<Null>>(() async {
    runApp(new CrashyApp());
  }, onError: (error, stackTrace) async {
    await _reportError(error, stackTrace);
  });
}

class CrashyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Crashy',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('Crashy'),
      ),
      body: new Center(
        child: new Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            new RaisedButton(
              child: new Text('Dart exception'),
              elevation: 1.0,
              onPressed: () {
                throw new StateError('This is a Dart exception.');
              },
            ),
            new RaisedButton(
              child: new Text('async Dart exception'),
              elevation: 1.0,
              onPressed: () async {
                foo() async {
                  throw new StateError('This is an async Dart exception.');
                }
                bar() async {
                  await foo();
                }
                await bar();
              },
            ),
            new RaisedButton(
              child: new Text('Java exception'),
              elevation: 1.0,
              onPressed: () async {
                final channel = const MethodChannel('crashy-custom-channel');
                await channel.invokeMethod('blah');
              },
            ),
            new RaisedButton(
              child: new Text('Handled exception'),
              elevation: 1.0,
              onPressed: () async {
                try {
                  throw new FormatException('Expected at least 1 section');
                } catch (ex, st) {
                  Bugsee.logException(exception: ex, handled: true, stackTrace: st);
                }
              },
            ),
            new RaisedButton(
              child: new Text('Network request'),
              elevation: 1.0,
              onPressed: () async {
                http.get('https://jsonplaceholder.typicode.com/posts/1');
              },
            ),
            new RaisedButton(
              child: new Text('Add Secure Rect'),
              elevation: 1.0,
              onPressed: () async {
                Rect hiddenRect = const Offset(50.0, 50.0) &
                                      const Size(100.0, 100.0);
                Bugsee.addSecureRect(rect: hiddenRect);
              },
            ),
            new RaisedButton(
              child: new Text('Remove Secure Rect'),
              elevation: 1.0,
              onPressed: () async {
                Rect hiddenRect = const Offset(50.0, 50.0) &
                                      const Size(100.0, 100.0);
                Bugsee.removeSecureRect(rect: hiddenRect);
              },
            ),
            new RaisedButton(
              child: new Text('Custom events'),
              elevation: 1.0,
              onPressed: () async {
                dynamic params = <String, dynamic>{};
                params['string'] = 'test';
                params['int'] = 5;
                params['float'] = 0.55;
                params['bool'] =  true;
                Bugsee.event(name: 'event', parameters: params);
                Bugsee.trace(name: 'number', value: 5);
                Bugsee.trace(name: 'float', value: 0.55);
                Bugsee.trace(name: 'string', value: 'test');
                Bugsee.trace(name: 'bool', value: true);
                Bugsee.trace(name: 'map', value: params);
                Bugsee.setAttribute(key: 'age', value: 36);
                Bugsee.setAttribute(key: 'name', value: 'John Doe');
                Bugsee.setAttribute(key: 'married', value: false);
              },

            ),
          ],
        ),
      ),
    );
  }
}

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  bugsee: "^1.0.3"

2. Install it

You can install packages from the command line:

with Flutter:


$ flutter packages get

Alternatively, your editor might support packages get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:bugsee/bugsee.dart';
        
Version Uploaded Documentation Archive
1.0.3 Apr 20, 2018 Go to the documentation of bugsee 1.0.3 Download bugsee 1.0.3 archive
1.0.2 Apr 14, 2018 Go to the documentation of bugsee 1.0.2 Download bugsee 1.0.2 archive
1.0.1 Apr 14, 2018 Go to the documentation of bugsee 1.0.1 Download bugsee 1.0.1 archive
1.0.0 Apr 11, 2018 Go to the documentation of bugsee 1.0.0 Download bugsee 1.0.0 archive

Analysis

We analyzed this package on Apr 23, 2018, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.0.0-dev.49.0
  • pana: 0.10.6
  • Flutter: 0.3.2

Scores

Popularity:
Describes how popular the package is relative to other packages. [more]
0 / 100
Health:
Code health derived from static analysis. [more]
99 / 100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
100 / 100
Overall score:
Weighted score of the above. [more]
50
Learn more about scoring.

Platforms

Detected platforms: Flutter

References Flutter, and has no conflicting libraries.

Suggestions

  • The description is too short.

    Add more detail about the package, what it does and what is its target use case. Try to write at least 60 characters.

  • Fix analysis and formatting issues.

    Analysis or formatting checks reported 1 hint.

    Run flutter format to format lib/bugsee.dart.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=1.8.0 <2.0.0
crypto 2.0.2+1 2.0.2+1
flutter 0.0.0
stack_trace >=1.0.0 <2.0.0 1.9.2
Transitive dependencies
charcode 1.1.1
collection 1.14.6 1.14.9
convert 2.0.1
meta 1.1.2
path 1.5.1
sky_engine 0.0.99
typed_data 1.1.5
vector_math 2.0.6