Как я могу проверить, какое исключение вызвало сценарий или eval
блок для завершения? Я должен знать тип ошибки, и где исключение произошло.
Идиоматический Perl заключается в том, что мы либо игнорируем все ошибки, либо перехватываем их для логирования или пересылки в другое место:
eval { func() }; # ignore error
или:
eval { func() };
if ($@) {
carp "Inner function failed: $@";
do_something_with($@);
}
или (используя Try::Tiny - см. на этой странице причины, почему вы можете захотеть использовать его вместо встроенной обработки исключений Perl):
try { func() }
catch {
carp "Inner function failed: $_";
do_something_with($_);
};
Если вы хотите проверить тип исключения, используйте regexes:
if ( $@ =~ /open file "(.*?)" for reading:/ ) {
# ...
}
Строка и файл также находятся в этой строке.
Однако это довольно неприятно, потому что вам нужно знать точную строку. Если вам действительно нужна хорошая обработка ошибок, используйте модуль исключений из CPAN.
$@ не обязательно должен быть строкой, это может быть объект. Exception::Class позволяет объявлять и бросать объекты исключений в стиле Java. Вы можете передать произвольную информацию (имя файла и т.д.) вместе с ошибкой, когда вы ее бросаете, и получить эту информацию, используя методы объекта, а не разбор regex - включая файл и номер строки исключения.
Если вы используете сторонний модуль, который не использует Error::Exception, рассмотрите
$SIG{__DIE__} = sub { Exception::Class::Base->throw( error => join '', @_ ); };
Это преобразует все ошибки в объекты Exception::Class.
Error::Exception устанавливает правильную структуризацию для объектов Exception::Class.