React Native - правильная обработка ошибок API-интерфейса - PullRequest
0 голосов
/ 31 августа 2018

Я довольно новичок в 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 вызывает красный экран ошибки для пользователя. Очевидно, это не то, чего я хочу.

Мне в основном не хватает знаний, чтобы знать, как лучше всего справляться с подобными проблемами, поэтому, несмотря на то, что я могу придумать разные способы решения этой проблемы, это не значит, что я делать то, что лучше всего.

То, что я сделал или рассмотрел:

  1. В методе проверки состояния я просто удалил строку ошибки выброса и возвратил ответ.

Это не имеет большого смысла для меня, так как эта проверка состояния является общей и должна обрабатывать многие типы сценариев, которые могут возникнуть. Так и происходит с ответом RBAC, который мне действительно безразличен, поскольку данные никогда не запрашивались на сервере.

  1. Я рассмотрел возможность добавления дополнительных условий для проверки на 401 и возврата ответа в этом сценарии.

Это на самом деле не решает проблему с красным экраном, так как то же самое случится с любой ошибкой, например, с 500. Возможно, частью проблемы является мой код, и я не правильно исправляю ошибки.

Да, я знаю, что использование Observables не было разумным занятием. Я сделал это вначале из англовского мира и подумал, что это было бы здорово. По ходу дела я узнал, что использование приставки сводит на нет большинство преимуществ использования наблюдаемых в сетевых запросах. Я планирую удалить код позже, но не могу сделать это прямо сейчас.

Любая помощь и совет будут с благодарностью. Заранее спасибо.

...