Встроенная обработка ошибок ECL lisp

#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 «Привет»)?