#error-handling #lisp #common-lisp #ecl
#обработка ошибок #lisp #common-lisp #ecl
Вопрос:
Задача: внедрить ECL lisp в мой проект, настроить обработку ошибок и подробные отчеты об ошибках (где произошла, тип ошибки и т. Д.)
Я пытался сделать это таким образом:
cl_def_c_function_va(
c_string_to_object("SYSTEM:UNIVERSAL-ERROR-HANDLER"),
LispErrorHandler);
У ECL нет документации по встроенному API и документации по обработке ошибок…
Можете ли вы предложить, как это реализовать?
Ответ №1:
Глобального обработчика ошибок не существует, поскольку это не соответствует философии Common Lisp. Если вы хотите обрабатывать ошибки, делайте это способом lisp.
1) Создайте функцию, которая использует HANDLER-CASE или HANDLER-BIND для настройки соответствующих обработчиков ошибок и отслеживания ошибок вокруг формы, которая должна быть оценена. Что-то вроде
(DEFUN MY-EVAL (FORM) (HANDLER-CASE (EVAL FORM) (ОШИБКА (C) …) (МОЯ ОШИБКА (C) …) …))
Эта функция может быть определена в вашем коде на C и вызываться.
2) Используйте функции, созданные ECL, которые улавливают все ошибки. Наиболее важным является si_safe_eval(форма, среда, error_value). Он оценивает ФОРМУ lisp в СРЕДЕ (обычно Cnil) и возвращает ее выходные данные или ERROR_VALUE, если в ней произошла какая-либо ошибка.
Некоторые примеры, в которых используется тот или иной метод: http://thread.gmane.org/gmane.lisp.ecl.general/5365 (2-е сообщение) http://thread.gmane.org/gmane.lisp.ecl.general/8526/focus=8529
Комментарии:
1. … Но попробуйте оценить
(defun SYSTEM:UNIVERSAL-ERROR-HANDLER (a1 a2 a3) t)
, а затем(qwertyuiop)
сообщение об ошибке подразумевает, что функция существует (1) и может быть закодирована / изменена (2). Вы уверены, что мы не можемt use that? It is not a 'tedium', but 'scientific' interest, you may not answer, if you don
хотеть 😉 Еще раз спасибо!2. пожалуйста, с системой: универсальный обработчик ошибок не следует связываться. Если вы хотите изменить обработчик ошибок, используйте стандарт Common Lisp. Эта функция существует только для внутренних целей, и вы пытаетесь предположить, что ее можно переопределить, когда это невозможно. Он используется внутренне СИГНАЛОМ Common Lisp таким образом, который не должен быть открыт пользователю. Перехват не приводит к тому, что ошибки просто исчезают — правильная обработка ошибок ожидается везде в ECL. Что произойдет, если вы переопределите эту функцию, а затем выполните вычисление (SIN «Привет»)?