Git Product home page Git Product logo

redux-bug-reporter's Introduction

Redux Bug Reporter

Authors: Drew Schuster & Greg Mathews

npm version npm downloads build coverage license js-standard-style

Demo

✨DEMO ✨

Prototype Demo Video

Features

  • Easy Bug Filing - Any user is able to easily file bugs right from your application
  • Redux logging - Any bug filed automatically passes along everything needed to recreate the bug. Initial redux state, all actions performed, and final redux state
  • Redaction - Customizable hooks allow for redaction of any sensitive information in redux state or in action payloads before bug submission
  • Easy Playback of Bug - A global function window.bugReporterPlayback is available to replay any bug
  • Automatic Logging of browser errors - Any calls to console.error or window.onError are filed with a bug automatically
  • Automatic Browser Info logging - All bugs filed automatically include window dimensions, window location, and user agent
  • Extensible
    • Extra properties passed in as meta to the Redux Bug Reporter component are filed alongside the bug
    • Submit property can either be a URL or a custom function that returns a promise. This should allow Redux Bug Reporter to work in any development environment
  • Integration With Bug Trackers
    • Ships with integration for Jira, GitHub Issues, Asana, Taiga, and Google Sheets (via Sheetsu)
    • Easy to write custom integration with other bug trackers
    • Integration Documentation

Installation

The easiest way to use Redux Bug Reporter is to install it from npm and include it in your own build process (Webpack, Browserify, etc)

$ npm install --save redux-bug-reporter

A UMD build is also available:

<link rel="stylesheet" href="redux-bug-reporter/dist/redux-bug-reporter.min.css">
<script src="redux-bug-reporter/dist/redux-bug-reporter.min.js"></script>

Performance and Production Use

Redux Bug Reporter puts minimal overhead on redux actions. However, it does keep copies of initial state, final state on bug submission, and full copies of all actions dispatched. For an application with heavy actions (such as network requests with large payloads) or very frequent actions, Redux Bug Reporter will gradually take up more and more memory. As such, it's probably a good idea to disable in production by default. The examples below demonstrate the expected common behavior of only enabling Redux Bug Reporter in non-production environments.

What about server-side rendering?

Redux Bug Reporter disables itself by default if window is undefined, so it will not negatively impact server side renders.

But can it run in production?

Redux Bug Reporter can run in production. It's assumed that an application usually wouldn't want the bug reporter to be displayed on the page and allow public users to file bugs, but if that is the desired behavior Redux Bug Reporter does work in production.

Usage

1. Use with Redux

Update your configure store:

function configureStore(initialState) {
  const store = createStore(reducer, initialState, compose(
    applyMiddleware(...middleware)
  ));
  return store;
}

becomes

// ES6
import {storeEnhancer} from 'redux-bug-reporter'
// ES5
var storeEnhancer = require('redux-bug-reporter').storeEnhancer

function configureStore(initialState) {
  const store = createStore(reducer, initialState, compose(
    process.env.NODE_ENV !== 'production' ? storeEnhancer : f => f,
    applyMiddleware(...middleware)
  ));
  return store;
}

or if you don't have other store enhancers and middlewares

// ES6
import {storeEnhancer} from 'redux-bug-reporter'
// ES5
var storeEnhancer = require('redux-bug-reporter').storeEnhancer

function configureStore(initialState) {
  const store = createStore(reducer, initialState,
    process.env.NODE_ENV !== 'production' ? storeEnhancer : f => f
  );
  return store;
}

2. Render UI Component

// ES6
import ReduxBugReporter from 'redux-bug-reporter'
import 'redux-bug-reporter/dist/redux-bug-reporter.css'
// ES5
var ReduxBugReporter = require('redux-bug-reporter').default
require('redux-bug-reporter/dist/redux-bug-reporter.css')

const ParentContainer = () => {
    return (
        <div>
          This is your app, already wrapped in a Provider from react-redux
          {process.env.NODE_ENV !== 'production' && <ReduxBugReporter submit='http://localhost/path/to/post/bug/to' projectName='Test'/>}
        </div>
    )
}

3. Integrate With Backend Service

Redux Bug Reporter needs to be able to submit bugs to some sort of backend. Redux Bug Reporter ships with integrations to many common bug trackers. See the integration docs to set one up. If a backend service doesn't exist, a temporary solution to try Redux Bug Reporter is to log bugs to the console instead of submitting them.

import submitFn from 'redux-bug-reporter/lib/integrations/console'

// Later, in render
<ReduxBugReporter submit={submitFn} projectName='example'/>

4. Replay Filed Bugs

To replay a filed bug, call the global bugReporterPlayback function with the appropriate parameters:

window.bugReporterPlayback(actions, initialState, state, delay)

The delay parameter is the amount of time (in ms) between actions during playback. The default value is 100. Note: Setting a delay value of -1 will skip playback and just set the redux store state to be equal to the final state of the bug. This is useful in situations where an application maintains critical state outside of redux and playback does not work.

Prop Types

Property Type Default Description
submit Function or String Required If a string, the URL to post a bug to. If a function, a function called that will submit the bug. Note: function must return a promise
projectName String Required Name of the project the bug should be filed against. This can be used to scope bugs between different initiatives
redactStoreState Function optional A function that receives the state and returns a redacted state before bug submission. Warning: Should not alter passed in state See Redacting Sensitive Data
name String optional If the application knows the name of the user, this can be used to prepopulate the submission form
meta Any optional If meta exists, it will be passed along on bug submission
customEncode Function optional A function that receives the state and returns a new encoded state before bug submission (useful for serializing immutable objects)
customDecode Function optional A function that receives the state and returns a new decoded state before bug playback (useful for deserializing immutable objects)

Redacting Sensitive Data

Since Redux Bug Reporter logs all redux state and actions, there could easily be sensitive information in submitted bugs. There are two ways to redact information before submission.

Redacting Information from Store State

Pass in a redaction function as the redactStoreState prop to the ReduxBugReporter component. It will be applied to the initial store state and the final store state before bug submission.

let redactStoreState = function (state) {
    // Deep Clone the state to prevent altering actual state
    let newState = _.cloneDeep(state)
    if (newState && newState.identity && newState.identity.name) {
        newState.identity.name = 'REDACTED'
    }
    return newState
}

// Later, in render
<ReduxBugReporter submit='http://localhost/path/to/post/bug/to' projectName='Test' redactStoreState={redactStoreState}/>

Redacting Information from Action Payloads

In order to redact information from a payload of an action, set action.meta.redactFromBugReporter to true. If that boolean exists and no custom redaction function is specified, all that will be logged for the action is its type. A custom redaction function can be specified by creating it at action.meta.redactFromBugReporterFn. If redactFromBugReporterFn exists, the action will be deep cloned and passed in to the redaction function, which will return the sanitized action and payload.

let action {
    type: 'SIMPLE_ACTION',
    sensitiveField: 'SECRETS',
    meta: {
        redactFromBugReporter: true,
        unrelatedMeta: true
    }
}
// Redacted action is { type: 'SIMPLE_ACTION', meta: { unrelatedMeta: true } }

let action {
    type: 'CUSTOM_REDACTION_ACTION',
    sensitiveField: 'SECRETS',
    nonSensitiveField: 'Foo Bar'
    meta: {
        redactFromBugReporter: true,
        redactFromBugReporterFn: function (action) {
            delete action.sensitiveField
            return action
        },
        unrelatedMeta: true
    }
}
// Redacted action is { type: 'CUSTOM_REDACTION_ACTION', nonSensitiveField: 'Foo Bar', meta: { unrelatedMeta: true } }

Working with ImmutableJS or similar libraries

To file and replay bugs, redux-bug-reporter needs to submit redux state as a JSON object and receive redux state as a JSON object. If all or part of your redux store is using a library such as immutable, you will need to pass in the customEncode and customDecode properties to <ReduxBugReporter>.

/* Assume your redux state is of the form
{
    immutableState: IMMUTABLE_OBJECT,
    normalMutableState: { foo: true }
}
*/
import { fromJS } from 'immutable'
const customEncode = (state) => {
    return {
        immutableState: state.immutableState.toJSON(),
        mutableState: state.mutableState
    }
}

const customDecode = (state) => {
    return {
        immutableState: fromJS(state.immutableState),
        mutableState: state.mutableState
    }
}

// Later, when rendering Redux Bug Reporter
<ReduxBugReporter submit='http://localhost/path/to/post/bug/to' projectName='Test' customEncode={customEncode} customDecode={customDecode}/>

Contributions

  • Fork the project
  • Make changes
  • Double check changes work by adding it to the examples
  • Confirm that tests still pass
  • Write new tests if applicable
  • Update README with appropriate docs
  • Commit and create a PR

License

MIT

Analytics

redux-bug-reporter's People

Contributors

bryant1410 avatar dtschust avatar larsw avatar matthewbdaly avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

redux-bug-reporter's Issues

Would this work with Immutable state aswel?

I'm considering using this inside of a client's application. But we use Immutable.js for our store.
Would this still work or would you need to use the .toJS() and .fromJS() functions to reproduce?

If so maybe you want to document an example.

Update to standard 8.0.0

Hi,

After I synced my local working copy with your repo, I get the following error when I try to bring my forked github repo up to speed:

C:\code\redux-bug-reporter\example\index.js:62:24: A space is required before closing bracket
C:\code\redux-bug-reporter\example\index.js:63:27: A space is required before closing bracket
C:\code\redux-bug-reporter\example\index.js:65:111: A space is required before closing bracket
C:\code\redux-bug-reporter\example\index.js:83:92: A space is required before closing bracket
C:\code\redux-bug-reporter\example\index.js:121:22: A space is required before closing bracket
C:\code\redux-bug-reporter\example\webpack.example.config.js:8:5: Use path.join() or path.resolve() instead of + to create paths.
C:\code\redux-bug-reporter\src\redux-bug-reporter.js:15:16: A space is required before closing bracket
C:\code\redux-bug-reporter\src\redux-bug-reporter.js:227:170: A space is required before closing bracket
C:\code\redux-bug-reporter\src\redux-bug-reporter.js:238:184: A space is required before closing bracket
C:\code\redux-bug-reporter\src\redux-bug-reporter.js:239:200: A space is required before closing bracket
C:\code\redux-bug-reporter\src\redux-bug-reporter.js:240:209: A space is required before closing bracket
C:\code\redux-bug-reporter\src\redux-bug-reporter.js:241:179: A space is required before closing bracket
C:\code\redux-bug-reporter\src\redux-bug-reporter.js:247:189: A space is required before closing bracket
C:\code\redux-bug-reporter\src\redux-bug-reporter.js:256:5: Expected indentation of 2 space characters but found 4.
C:\code\redux-bug-reporter\src\redux-bug-reporter.js:258:54: A space is required before closing bracket
C:\code\redux-bug-reporter\webpack.config.js:7:5: Use path.join() or path.resolve() instead of + to create paths.
C:\code\redux-bug-reporter\webpack.config.js:8:5: Use path.join() or path.resolve() instead of + to create paths.
C:\code\redux-bug-reporter\webpack.config.js:11:11: Use path.join() or path.resolve() instead of + to create paths.

maxHistoryToRetain configuration option

I recently reached out to @dtschust in regards to to retaining history state in a production environment.

To quote the readme:

...For an application with heavy actions (such as network requests with large payloads) or very frequent actions, Redux Bug Reporter will gradually take up more and more memory. As such, it's probably a good idea to disable in production by default...

I would love to have a configuration where you could control the amount of state / (state) history saved this way.
A simple configuration of maxHistoryToRetain or a maxActionsToRetain

To quote @dtschust:

... That way as you use the app, redux bug reporter would only keep track of at most N actions, and when you filed a bug you'd be sent the state of the store before those N actions, the actions themselves, and the final state of the store.

In short a way to tighten the knit on the state/action history buckling up in a production environment.

Unable to collect coverage information (Windows)

Hi,

I'm trying to get the code coverage reporting to work on Windows. First thing I spotted, was that the
following syntax is not allowed:
"babel-node $(npm bin)/isparta cover _mocha -- --recursive --require test/setup.js"

I tried the following instead:

> babel-node node_modules/isparta/bin/isparta cover node_modules/mocha/bin/_mocha -- --recursive --require test/setup.js

  Redux Bug Reporter component tests
    Server side render tests
      √ Server side render
    Client side render tests
      √ Happy path (241ms)
      √ customEncode and customDecode properties (230ms)
      √ Custom submit function (210ms)
      √ Error listeners
      √ window.onerror listeners when window.onerror already exists

  Store Enhancer tests
Overriding the store. You should only be doing this if you are using the bug reporter
    √ bug playback functionality
    √ middleware functionality

  8 passing (736ms)

No coverage information was collected, exit without writing coverage information

But as the report says, no coverage information was collected. I've also tried to update mocha to 3.0.2. isparta@latest as far as I can tell.

Add Chat

When new adopters have questions they could ask them without creating issues. Besides that contributors can discuss design patterns and work to be done.

I would suggest Gitter chat.

When using a personal access token with github, receive 422 error

{
  "message": "Validation Failed",
  "errors": [
    {
      "resource": "Issue",
      "code": "custom",
      "field": "body",
      "message": "body is too long (maximum is 65536 characters)"
    }
  ],
  "documentation_url": "https://developer.github.com/v3/issues/#create-an-issue"
}

Not sure if this is even fixable, so if not, perhaps mention in the docs?

React 16 support

Hi @dtschust, thanks for building redux-bug-reporter! I have one question though. Do you have any plans to support React 16 in order to get rid of the deprecation warning regarding React.createClass in React 15.5?

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.