mattermost-mobile/service/actions/helpers.js
Chris Duarte e17eb6c237 PLT-5709 Global error handler (#187)
* WIP Global error handler

Adding components
Adding actions

* Add general errors where errors are caught

* Filter out non displayable errors

* Initial setup to email errors

* Add current user/team to error email

* Fix a few lints

* Ensure errors are cleared when reporting a problem

* Add clear all and internationalization

* Fix trailing comma issue

* fix lints

* Use Formatted Text component

* Move error list out of channel

* Add mobile prefix to i18n id for connection error

* Set shouldRender to true in RightMenuDrawerItem.defaultProps

* Update component name for RightMenuDrawerItem

* Clean up propTypes in RightMenuDrawerItem

* Clean up styles in RightMenuDrawerItem

* Use selector to filter displayable errors

* Clarify code for constructing wrapper style in ErrorList

* Avoid indenting email body for error report

* Remove extraneous params from errors actions

* Rename action type for logging errors

* Rename action for logging errors

* Set shouldRender to true in RightMenuDrawerItem.defaultProps

* Make logged errors displayable by default

* Don't log error when websocket connection is closed

* Hide button to dismiss all errors if ShowErrorsList isn't enabled

* Display only last error in alert bar when ShowErrorsList is disabled

* Add error logging where missing in actions

* Always show button to report problem

* Only include errors in report problem email if any have been logged

* Clarify subject of report problem email

* Set ShowErrorsList to false in default config.json

* Remove unused component + translation for connection errors

* Capture entire error object not just message

* Display fallback if error.message is blank

* Log errors in login actions

* Fix construction of errors email body
2017-03-12 14:42:02 -03:00

106 lines
2.8 KiB
JavaScript

// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import {batchActions} from 'redux-batched-actions';
import Client from 'service/client';
import {UsersTypes} from 'service/constants';
import {getLogErrorAction} from './errors';
const HTTP_UNAUTHORIZED = 401;
export async function forceLogoutIfNecessary(err, dispatch) {
if (err.status_code === HTTP_UNAUTHORIZED && err.url.indexOf('/login') === -1) {
dispatch({type: UsersTypes.LOGOUT_REQUEST});
await Client.logout();
dispatch({type: UsersTypes.LOGOUT_SUCCESS});
}
}
function dispatcher(type, data, dispatch, getState) {
if (type.indexOf('SUCCESS') === -1) { // we don't want to pass the data for the request types
dispatch(requestSuccess(type, data), getState);
} else {
dispatch(requestData(type), getState);
}
}
export function requestData(type) {
return {
type
};
}
export function requestSuccess(type, data) {
return {
type,
data
};
}
export function requestFailure(type, error) {
return {
type,
error
};
}
export function bindClientFunc(clientFunc, request, success, failure, ...args) {
return async (dispatch, getState) => {
dispatch(requestData(request), getState);
let data = null;
try {
data = await clientFunc(...args);
} catch (err) {
forceLogoutIfNecessary(err, dispatch);
dispatch(batchActions([
requestFailure(failure, err),
getLogErrorAction(err)
]), getState);
return;
}
if (Array.isArray(success)) {
success.forEach((s) => {
dispatcher(s, data, dispatch, getState);
});
} else {
dispatcher(success, data, dispatch, getState);
}
};
}
// Debounce function based on underscores modified to use es6 and a cb
export function debounce(func, wait, immediate, cb) {
let timeout;
return function fx(...args) {
const runLater = () => {
timeout = null;
if (!immediate) {
Reflect.apply(func, this, args);
if (cb) {
cb();
}
}
};
const callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(runLater, wait);
if (callNow) {
Reflect.apply(func, this, args);
if (cb) {
cb();
}
}
};
}
export class FormattedError extends Error {
constructor(id, defaultMessage, values = {}) {
super(defaultMessage);
this.intl = {
id,
defaultMessage,
values
};
}
}