Я создаю приложение React + Redux, и сейчас я работаю над функцией, которая извлекает определенное количество закладок пользователя на страницу.
Это выглядит так: когда пользователь добавляет ресурс в закладки, идентификатор ресурса сохраняется в базе данных и ассоциируется с пользователем. Таким образом, функция, над которой я работаю, получает идентификаторы закладок пользователя и делает запросы API для получения дополнительной информации о каждом ресурсе и отображения их пользователю в списке. Все запросы API заключены в Promise.all().
Моя проблема в том, что если ресурс, отмеченный пользователем, был удален, запрос API, очевидно, приводит к ошибке 404, что приводит к ошибке Promise.all(), даже если другие запросы выполнены успешно. Итак, как я могу игнорировать ошибку этого единственного неудачного запроса и продолжать работать с успешными?
Вот моя функция:
export const fetchUserBookmarks = ( bookmarkType, reset ) => async ( dispatch, getState, api ) => {
if ( reset ) {
dispatch({
type: 'RESET_BOOKMARKS'
});
}
var endpoint;
if ( bookmarkType == 'projects' ) {
endpoint = 'posts';
} else if ( bookmarkType == 'images' ) {
endpoint = 'media';
} else {
endpoint = bookmarkType;
}
const bookmarksIDs = getState().currentUser.bookmarks.IDs[ bookmarkType ];
const bookmarksPerPage = getState().currentUser.bookmarks.perPage;
const start = bookmarksPerPage * getState().currentUser.bookmarks[ bookmarkType ].resultsPage;
const end = start + bookmarksPerPage;
const bookmarksSet = bookmarksIDs.slice( start, end );
const BOOKMARKTYPE = bookmarkType.toUpperCase();
dispatch({
type: 'IS_FETCHING_BOOKMARKED_' + BOOKMARKTYPE,
});
try {
const bookmarks = [];
const getBookmarks = await Promise.all(
bookmarksSet.map( bookmarkID =>
api.get( '/wp-json/wp/v2/' + endpoint + '/' + bookmarkID )
)
);
getBookmarks.map( request => {
bookmarks.push( request.data )
});
dispatch({
type: 'HAS_FETCHED_BOOKMARKED_' + BOOKMARKTYPE,
payload: bookmarks
});
} catch( error ) {
if ( error.response !== undefined && error.response.status == 401 ) {
dispatch({
type: 'IS_EMPTY_BOOKMARKED_' + BOOKMARKTYPE
});
} else {
dispatch({
type: 'FAILED_FETCHING_BOOKMARKED_' + BOOKMARKTYPE
});
}
}
}





Расширяя комментарий @nikrb - вы можете отловить все 404 ошибки в своих запросах.
Не зная формата ответа API, соответствующий код может выглядеть примерно так:
const getBookmarks = await Promise.all(
bookmarksSet.map(bookmarkID =>
api.get('/wp-json/wp/v2/' + endpoint + '/' + bookmarkID)
.catch((error) => {
// avoid catching unexpected errors (not due to 404)
if (error.statusCode !== 404) {
throw error
}
})
)
);
У меня может быть для вас хак, которым я сейчас пользуюсь. Итак, что я делаю, когда нахожусь в ситуации, о которой вы упомянули, я избегаю использования блоков try / catch, а вместо этого создаю объект результатов. В последнее время я часто использую redux-saga, поэтому больше не попадаю в такую ситуацию.
В любом случае вот код, который я использую
const buildResultObject = (promise) => {
return promise
.then(result => ({ success: true, result }))
.catch(error => ({ success: false, error }));
};
Promise
.all([p1, p2, p3].map(buildResultObject))
.then(
results => {
results.map(response => {
if (response.success) {
console.info(response.result);
} else {
console.info(`Boom: ${response.error}`);
}
})
}
);
Можете ли вы обернуть каждое получение в обещание, а затем в catch, разрешить с сообщением, указывающим на неудачу?