Я довольно новичок в React Native и, кроме того, достиг 7-летнего опыта, не изучая правильную обработку ошибок в интерфейсе. Я писал как front, так и backend для этого конкретного приложения и столкнулся с ситуацией, в которой мне нужна ясность.
Я построил базовый уровень RBAC на бэкэнде, который выполняет различные проверки перед попаданием в конечные точки db. В этом выпуске RBAC проверяет, является ли пользователь администратором; если это не так, он возвращает статус 401, показанный ниже:
rbac.check(role, type, {
user: user,
[identifier]: resourceId
}, (err, result) => {
if (!result) {
return res.status(401).json({
success: false,
message: 'not authorized to access'
})
} else {
return next();
}
}
);
Насколько мне известно из чтения статей, это правильный подход (может быть ошибочным). Проблема возникает на моем веб-интерфейсе, который является приложением React Native, использующим API Fetch. У меня есть thunk, который вызывает метод службы, который вызывает общий метод службы http. Я обернул api fetch в наблюдаемую ниже:
// Thunk Code
const _getOrganizations = (organizations) => {
return {
type: Types.TYPES_ORGANIZATIONS_SET,
payload: organizations
};
};
export const getOrganizations = (userId) => {
return dispatch => {
return OrganizationService.getAll(userId)
.map(
_data => {
if (!_data['success'] && !_data['organizations']) {
_data['organizations'] = [];
}
dispatch(_getOrganizations(_data['organizations']));
return _data;
}, _error => { return _error; }
)
};
};
// Service method:
getAll(userId) {
return Http.$get(Constants.ENDPOINT_USER, userId, Constants.POSTFIX_ORGANIZATIONS);
}
// Http Service
$get(endpoint, id, postfix, auxId) {
let _postfix = (typeof postfix === 'undefined' || postfix === null) ? '' : postfix;
let _auxId = (typeof auxId === 'undefined' || auxId === null) ? '' : '/' + auxId;
return Observable.defer(() => {
return Observable.fromPromise(
fetch(this.apiUrl + endpoint + id + _postfix + _auxId, {
method: 'get',
headers: this._headers()
})
.then(this._checkStatus)
.then(res => res.json()));
}
);
}
Как видите, у обещания есть метод checkStatus в цепочке. Я добавил это, потому что это то, что я видел во всех примерах, как использовать API выборки. Мой метод checkStatus выглядит следующим образом:
/**
* Error Handling
*/
_checkStatus(response) {
if (response.status >= 200 && response.status < 300) {
return response;
} else {
let error = new Error(response.statusText);
error.response = response;
throw error;
}
}
Когда 401 возвращается из серверной части, выполняется оператор else, который выдает ошибку, которая в области React Native вызывает красный экран ошибки для пользователя. Очевидно, это не то, чего я хочу.
Мне в основном не хватает знаний, чтобы знать, как лучше всего справляться с подобными проблемами, поэтому, несмотря на то, что я могу придумать разные способы решения этой проблемы, это не значит, что я делать то, что лучше всего.
То, что я сделал или рассмотрел:
- В методе проверки состояния я просто удалил строку ошибки выброса и возвратил ответ.
Это не имеет большого смысла для меня, так как эта проверка состояния является общей и должна обрабатывать многие типы сценариев, которые могут возникнуть. Так и происходит с ответом RBAC, который мне действительно безразличен, поскольку данные никогда не запрашивались на сервере.
- Я рассмотрел возможность добавления дополнительных условий для проверки на 401 и возврата ответа в этом сценарии.
Это на самом деле не решает проблему с красным экраном, так как то же самое случится с любой ошибкой, например, с 500. Возможно, частью проблемы является мой код, и я не правильно исправляю ошибки.
Да, я знаю, что использование Observables не было разумным занятием. Я сделал это вначале из англовского мира и подумал, что это было бы здорово. По ходу дела я узнал, что использование приставки сводит на нет большинство преимуществ использования наблюдаемых в сетевых запросах. Я планирую удалить код позже, но не могу сделать это прямо сейчас.
Любая помощь и совет будут с благодарностью. Заранее спасибо.