Kodokon kodokon.com

Отладка и надёжность: try/catch, продвинутая консоль, свои ошибки

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

9 мин · 3 вопросов

Открыть этот урок в Kodokon

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

JAVASCRIPT
function parseConfig(json) {
  try {
    return JSON.parse(json);
  } catch (error) {
    console.error("Unreadable config:", error.message);
    throw error; // rethrow: nothing can be fixed here
  } finally {
    console.log("Finished reading configuration");
  }
}
Записать в лог, затем пробросить дальше: решать будет граница выше.

Простые строки - это ещё не стратегия ошибок. Наследуйся от Error, чтобы создавать классы, несущие структурированные данные (HTTP-статус, невалидное поле), которые можно различать через instanceof. Начиная с ES2022 опция cause сцепляет исходную ошибку с высокоуровневой: ты показываешь понятное бизнес-сообщение, не теряя технический след.

JAVASCRIPT
class ApiError extends Error {
  constructor(message, status, options) {
    super(message, options);
    this.name = "ApiError";
    this.status = status;
  }
}
try {
  const low = new Error("socket timeout");
  throw new ApiError("Profile unavailable", 503,
    { cause: low });
} catch (error) {
  if (error instanceof ApiError) {
    console.error(error.status, error.cause.message);
  }
}
Различимая бизнес-ошибка с сохранённой технической причиной.

Консоль предлагает куда больше, чем log: console.table выстраивает коллекции объектов, group/groupEnd вкладывает вывод, time/timeEnd измеряет длительность, console.assert пишет только тогда, когда условие ложно, а console.trace печатает текущий стек вызовов. Вместе эти инструменты уверенно бьют ливень безымянных log.

JAVASCRIPT
const users = [
  { name: "Ada", role: "admin" },
  { name: "Linus", role: "dev" },
];
console.table(users);
console.group("Checks");
console.assert(users.length > 0, "Empty list");
console.time("sort");
users.sort((a, b) => a.name.localeCompare(b.name));
console.timeEnd("sort");
console.groupEnd();
Структурированный вывод: таблица, группа, утверждение и таймер.

Проверка знаний

Убедись, что запомнил ключевые моменты этого урока.

  1. Когда выполняется блок finally?
    • Только если ошибки не было
    • Только если сработал catch
    • В любом случае, включая выход через return или throw
  2. Для чего нужна опция cause при создании ошибки?
    • Чтобы помешать ошибке распространяться
    • Чтобы приложить исходную ошибку и сохранить технический контекст
    • Чтобы автоматически задать HTTP-код статуса
    • Чтобы запустить новый catch
  3. Как ведёт себя console.assert(condition, message)?
    • Пишет сообщение, только если условие ложно
    • Выбрасывает исключение, если условие ложно
    • Пишет сообщение, только если условие истинно