Обработка ошибок в многоразовой функции выборки

#javascript #typescript

Вопрос:

Я пишу многоразовую функцию выборки (которая будет храниться в отдельном файле), и я не слишком уверен в том, как лучше всего обрабатывать функцию, возвращающую значение null.

Допустим, я хочу вызвать эту функцию и применить некоторую логику, когда getOrganizationInfo не возвращает информацию об организации. На данный момент моя функция возвращает ошибку, но попадает в первый if (organization) блок, и я действительно не могу с этим справиться. Затем мне нужно использовать это сообщение об ошибке, чтобы использовать его, например, в handleSubmit showError(error) . Что мне делать, чтобы воспользоваться этой else логикой?

 const orgName = 'ABC';

const handleSubmit = async () => {
  const organization = await getOrganizationInfo(orgName);
  
  if (organization) {
    // Do something
  } else {
    // Do something else
  }
}
 

Вот моя функция

 export const getOrganizationInfo = async (
  organizationName: string,
): Promise<OrganizationInfoResponse> => {
  let organizationInfoResponse: OrganizationInfoResponse;

  try {
    const rawRes = await fetch(`/sometestendpoint/${organizationName}`, {
      method: 'GET',
      headers: {
        'Content-Type': 'application/json',
      },
    });

    organizationInfoResponse = await rawRes.json();

    if (rawRes.status >= 400) {
      if (organizationInfoResponse.errorCode === ErrorCodes.INVALID_ORG_NAME) {
        throw new Error('Given Organization Name is invalid');
      } else {
        throw new Error('Unable to get organization information.');
      }
    }
  } catch (error) {
    // organizationInfoResponse = error.toString();
    throw new Error(error.toString());
  }

  return organizationInfoResponse;
};
 

Комментарии:

1. «В данный момент моя функция возвращает ошибку, но попадает в первый блок if (организация)» : код, которым вы поделились, этого не делает. Если getOrganizationInfo выдает ошибку, то handleSubmit возвращенное обещание будет отклонено без выполнения if...else блока.

2. Может быть, я неправильно это описал. organizationInfoResponse = error.toString(); в блоке catch возвращает строку, которая попадает в if истинный блок. В любом случае ни один из вариантов не дает желаемого результата. Я изо всех сил стараюсь, чтобы он перешел к другому, если есть ошибка.

3. Упасть в if блок? Здесь это невозможно: когда catch блок выполняется, вы выдаете ошибку-не возвращаете значение. Как следствие await , in handleSubmit предотвратит дальнейшее выполнение кода внутри handleSubmit . Ни то if , ни else другое не выполняется в таком случае.

Ответ №1:

Код, указанный в вашем вопросе, будет выполнять следующие действия, когда он попадет в catch блок:

  • Он выполняет throw new Error(error.toString())
  • Обещание в следующем выражении будет отклонено: await getOrganizationInfo(orgName)
  • Обещание, которое было возвращено, handleSubmit будет отвергнуто
  • Ни один из handleSubmit приведенных ниже кодов await не будет выполнен

Так что то, что вы утверждаете, что происходит, не происходит. Возможно , вы говорили о версии вашего кода, в которой в catch блоке этого не было throw , но вместо этого была строка с комментарием:

 catch (error) {
    organizationInfoResponse = error.toString();
}
 

В этом случае код «попадет в if «, потому что тогда ошибка будет проглочена вышеуказанным catch блоком:

  • Функция продолжается с return organizationInfoResponse
  • Обещание в следующем выражении будет выполнено: await getOrganizationInfo(orgName)
  • Контекст выполнения функции handleSubmit восстанавливается и organization присваивается значение выполнения (т. е. error.toString() )
  • if (organization) Условие является истинным, и поэтому if блок выполняется

Решение

Чтобы else выполнить блок, используйте throw версию вашего кода и либо введите try...catch блок handleSubmit , либо (проще) цепочку a .then и .catch вызовите обещание:

 const handleSubmit = () => {
  return getOrganizationInfo(orgName).then(organisation => {
    if (!organisation) throw new Error("Organisation is falsy");
    // Do something

  }).catch(error => {
    // Do something else

  });
}