Заставить javascript разработчика обрабатывать исключения - PullRequest
0 голосов
/ 16 января 2020

Чтобы описать возможность того, что функция может генерировать исключение, мы можем использовать JSDock

/**
 * @throws {Error}
 */
export const a = () => {
  throw new Error("i am exist only to throw exceptions...")
}

Хорошо, это мило. Но разработчик может пропустить это описание и не оборачивать функцию в try ... catch.

Как я могу заставить typcript / IDE / ES-lint сказать мне, что я забыл обернуть функцию в try ... .catch?

Должен ли я рассмотреть идею сделать плагин ES-lint? Или есть готовое решение? (кроме автотестов со всеми возможными аргументами)

Спасибо!

1 Ответ

0 голосов
/ 16 января 2020

try...catch является ситуативным - если вы хотите просто документ исключение в JSDo c и / или не можете самостоятельно обработать его (например, критическую ошибку), у вас возникнут проблемы с текущий подход.

Кроме того, ошибка идеально самодокументирована и обеспечивает определенное поведение в самом коде - все остальное не так, как DRY. Код / комментарии могут выйти из-под контроля c, вы можете также забыть документировать @throws {Error}.

Так что я не уверен, что плагин IDE или ES-lint - хорошая идея. Вместо этого вы можете создать некоторый тип данных Either, который заставит всех потребителей, возможно, вызывающей функции (a) реагировать на ошибку в какой-то момент - в противном случае они не получат возвращаемое значение обратно. Упрощенный пример:

// wrap a riscy throwing function, so that it returns a plain value ("purify it")
const tryCatch = (myRiskyFn) => {
  try {
    return { val: myRiskyFn() };
  } catch (e) {
    return { err: e };
  }
}

// enforce client to handle error branch here, so we can return a well defined value back.
const valueFromEither = (either, onError) =>
  "err" in either ? onError(either.err) : either.val;

// Test error case:
const a = () => { throw new Error("some error..."); };
const either1 = tryCatch(a); // throws internally
const result1 = valueFromEither(either1, err => `Oh my! ${err}`);
console.log(result1); // Oh my! Error: some error...

// Test success case:
const b = () => 42;
const either2 = tryCatch(b); // goes thru
const result2 = valueFromEither(either2, err => `Oh my! ${err}`);
console.log(`yay! ${result2}`); // yay! 42

(в стиле IO, Either, TaskEither в подходах функционального программирования, но вы можете просто использовать его самостоятельно!)

...