Yipit/redux-bug-reporter

Name: redux-bug-reporter

Owner: Yipit

Description: :bug: A bug reporter and bug playback tool for redux. :bug:

Created: 2017-10-21 19:06:22.0

Updated: 2017-10-21 19:06:23.0

Pushed: 2017-10-21 19:08:16.0

Homepage: null

Size: 1396

Language: JavaScript

GitHub Committers

UserMost Recent Commit# Commits

Other Committers

UserEmailMost Recent Commit# Commits

README

Redux Bug Reporter

Authors: Drew Schuster & Greg Mathews

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

Demo

?DEMO ?

Prototype Demo Video

Features
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)

m install --save redux-bug-reporter

A UMD build is also available:

k rel="stylesheet" href="redux-bug-reporter/dist/redux-bug-reporter.min.css">
ipt 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:

tion configureStore(initialState) {
nst store = createStore(reducer, initialState, compose(
applyMiddleware(...middleware)
;
turn store;

becomes

S6
rt {storeEnhancer} from 'redux-bug-reporter'
S5
storeEnhancer = require('redux-bug-reporter').storeEnhancer

tion configureStore(initialState) {
nst store = createStore(reducer, initialState, compose(
process.env.NODE_ENV !== 'production' ? storeEnhancer : f => f,
applyMiddleware(...middleware)
;
turn store;

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

S6
rt {storeEnhancer} from 'redux-bug-reporter'
S5
storeEnhancer = require('redux-bug-reporter').storeEnhancer

tion configureStore(initialState) {
nst store = createStore(reducer, initialState,
process.env.NODE_ENV !== 'production' ? storeEnhancer : f => f

turn store;

2. Render UI Component
S6
rt ReduxBugReporter from 'redux-bug-reporter'
rt 'redux-bug-reporter/dist/redux-bug-reporter.css'
S5
ReduxBugReporter = require('redux-bug-reporter').default
ire('redux-bug-reporter/dist/redux-bug-reporter.css')

t 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.

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

ater, in render
uxBugReporter submit={submitFn} projectName='example'/>
4. Replay Filed Bugs

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

ow.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.

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


ater, in render
uxBugReporter 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.

action {
type: 'SIMPLE_ACTION',
sensitiveField: 'SECRETS',
meta: {
    redactFromBugReporter: true,
    unrelatedMeta: true
}

edacted action is { type: 'SIMPLE_ACTION', meta: { unrelatedMeta: true } }

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

edacted 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>.

ssume your redux state is of the form

immutableState: IMMUTABLE_OBJECT,
normalMutableState: { foo: true }


rt { fromJS } from 'immutable'
t customEncode = (state) => {
return {
    immutableState: state.immutableState.toJSON(),
    mutableState: state.mutableState
}


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


ater, when rendering Redux Bug Reporter
uxBugReporter submit='http://localhost/path/to/post/bug/to' projectName='Test' customEncode={customEncode} customDecode={customDecode}/>
Contributions
License

MIT

Analytics


This work is supported by the National Institutes of Health's National Center for Advancing Translational Sciences, Grant Number U24TR002306. This work is solely the responsibility of the creators and does not necessarily represent the official views of the National Institutes of Health.