Clojure:
Обработка ошибок
Как:
Clojure, подобно своим предкам Lisp, опирается на исключения для обработки ошибок. Вот как вы показываете, на что вы способны, когда дела идут не так.
Генерирование исключения просто:
(throw (Exception. "Ой! Что-то пошло не так."))
Перехват исключения, это вы будете делать часто:
(try
;; рискованный код
(/ 1 0)
(catch ArithmeticException e
(println "Делить на ноль нельзя!"))
;; блок finally выполняется в любом случае
(finally
(println "Здесь идет код для очистки.")))
Пример вывода для приведенного выше блока catch:
Делить на ноль нельзя!
Здесь идет код для очистки.
Использование ex-info
и ex-data
для богатого контекста об исключениях:
(try
;; вызов пользовательского исключения
(throw (ex-info "Пользовательская ошибка" {:type :custom-failure}))
(catch Exception e
;; получаем данные из нашего пользовательского исключения
(println (ex-data e))))
Пример вывода:
{:type :custom-failure}
Глубокое Погружение
История обработки ошибок в Clojure не радикально отличается от других Lisps или даже Java (от которой он наследует механизм try-catch
). Это прагматично; использование исключений является основным путем, как и в Java, но Clojure предлагает функциональный вкус с ex-info
и ex-data
для более богатых данных об ошибке.
Альтернативы обработке ошибок в Clojure включают использование монадических конструкций, таких как монада either
из библиотек, вроде cats
, или core.async для передачи ошибок на основе каналов. Тем не менее, это более сложные методы и используются в конкретных сценариях.
Исторически, обработка ошибок в языках программирования развивалась от простых возвратов статуса до более сложных механизмов обработки исключений современных языков. Clojure выбрал простоту и элемент функционального программирования, смешивая старое и новое.
Смотрите также
- Руководство Clojure по исключениям: https://clojure.org/guides/exceptions
- Библиотека “Cats” для более функциональных подходов: https://github.com/funcool/cats
- “Core.async” для асинхронного программирования: https://github.com/clojure/core.async