Add missing rejection handling for Promises (#7008)

* Add eslint-plugin-promise to detect uncaught rejections

* Move alert generation for errors to actions/alert

* Add missing rejection handling for Promises

* Use catch() instead of onReject on then()

Then it will catches rejection from onFulfilled. This detection can be
disabled by `allowThen` option, though.
This commit is contained in:
unarist
2018-04-02 21:51:02 +09:00
committed by Eugen Rochko
parent e7a1716701
commit 2c51bc0ca5
13 changed files with 84 additions and 44 deletions

View File

@@ -103,7 +103,7 @@ export function fetchAccount(id) {
dispatch(importFetchedAccount(response.data));
})).then(() => {
dispatch(fetchAccountSuccess());
}, error => {
}).catch(error => {
dispatch(fetchAccountFail(id, error));
});
};

View File

@@ -1,3 +1,10 @@
import { defineMessages } from 'react-intl';
const messages = defineMessages({
unexpectedTitle: { id: 'alert.unexpected.title', defaultMessage: 'Oops!' },
unexpectedMessage: { id: 'alert.unexpected.message', defaultMessage: 'An unexpected error occurred.' },
});
export const ALERT_SHOW = 'ALERT_SHOW';
export const ALERT_DISMISS = 'ALERT_DISMISS';
export const ALERT_CLEAR = 'ALERT_CLEAR';
@@ -22,3 +29,21 @@ export function showAlert(title, message) {
message,
};
};
export function showAlertForError(error) {
if (error.response) {
const { data, status, statusText } = error.response;
let message = statusText;
let title = `${status}`;
if (data.error) {
message = data.error;
}
return showAlert(title, message);
} else {
console.error(error);
return showAlert(messages.unexpectedTitle, messages.unexpectedMessage);
}
}

View File

@@ -1,11 +1,12 @@
import api from '../api';
import { CancelToken } from 'axios';
import { CancelToken, isCancel } from 'axios';
import { throttle } from 'lodash';
import { search as emojiSearch } from '../features/emoji/emoji_mart_search_light';
import { tagHistory } from '../settings';
import { useEmoji } from './emojis';
import { importFetchedAccounts } from './importer';
import { updateTimeline } from './timelines';
import { showAlertForError } from './alerts';
let cancelFetchComposeSuggestionsAccounts;
@@ -291,6 +292,10 @@ const fetchComposeSuggestionsAccounts = throttle((dispatch, getState, token) =>
}).then(response => {
dispatch(importFetchedAccounts(response.data));
dispatch(readyComposeSuggestionsAccounts(token, response.data));
}).catch(error => {
if (!isCancel(error)) {
dispatch(showAlertForError(error));
}
});
}, 200, { leading: true, trailing: true });

View File

@@ -1,5 +1,6 @@
import api from '../api';
import { importFetchedAccounts } from './importer';
import { showAlertForError } from './alerts';
export const LIST_FETCH_REQUEST = 'LIST_FETCH_REQUEST';
export const LIST_FETCH_SUCCESS = 'LIST_FETCH_SUCCESS';
@@ -236,7 +237,7 @@ export const fetchListSuggestions = q => (dispatch, getState) => {
api(getState).get('/api/v1/accounts/search', { params }).then(({ data }) => {
dispatch(importFetchedAccounts(data));
dispatch(fetchListSuggestionsReady(q, data));
});
}).catch(error => dispatch(showAlertForError(error)));
};
export const fetchListSuggestionsReady = (query, accounts) => ({

View File

@@ -116,14 +116,11 @@ export function register () {
pushNotificationsSetting.remove(me);
}
try {
getRegistration()
.then(getPushSubscription)
.then(unsubscribe);
} catch (e) {
}
});
return getRegistration()
.then(getPushSubscription)
.then(unsubscribe);
})
.catch(console.warn);
} else {
console.warn('Your browser does not support Web Push Notifications.');
}
@@ -143,6 +140,6 @@ export function saveSettings() {
if (me) {
pushNotificationsSetting.set(me, data);
}
});
}).catch(console.warn);
};
}

View File

@@ -1,5 +1,6 @@
import api from '../api';
import { debounce } from 'lodash';
import { showAlertForError } from './alerts';
export const SETTING_CHANGE = 'SETTING_CHANGE';
export const SETTING_SAVE = 'SETTING_SAVE';
@@ -23,7 +24,9 @@ const debouncedSave = debounce((dispatch, getState) => {
const data = getState().get('settings').filter((_, path) => path !== 'saved').toJS();
api(getState).put('/api/web/settings', { data }).then(() => dispatch({ type: SETTING_SAVE }));
api(getState).put('/api/web/settings', { data })
.then(() => dispatch({ type: SETTING_SAVE }))
.catch(error => dispatch(showAlertForError(error)));
}, 5000, { trailing: true });
export function saveSettings() {