Ошибка подключения DBI (...): ORA-12154:
TNS: не удалось разрешить соединение
указанный идентификатор (DBD ERROR:
OCIServerAttach) в ...
Как бы я поймал это?
Чтобы поймать и обработать этот уровень ошибки, используйте eval в блочной форме "eval {...}". Это поймает любой кубик, который происходит в подкоде. Если код внутри блока eval умрет, он установит $ @, и блок вернет false. Если код не умирает, $ @ будет установлен в ''.
Использование обработки сигналов через SIG {WARN} и SIG {DIE} проблематично, поскольку они глобальны, также необходимо учитывать условия гонки (что произойдет, если я получу сигнал во время обработки другого сигнала? И т. Д.) традиционные проблемы обработки сигналов на основе). Вы, вероятно, пишете однопоточный код, поэтому вас не волнуют проблемы параллелизма нескольких вещей, вызывающих die, но есть пользователь, который нужно учитывать (возможно, он отправит SIGKILL, когда вы пытаетесь открыть соединение DBI )
В этом конкретном случае вы используете DBI. С помощью DBI вы можете контролировать то, что происходит в случае ошибки, если она молча умирает, предупреждает или терпит неудачу и ждет, пока вы проверите состояние возврата.
Вот базовый пример использования eval {...}.
my $dbh = eval { DBI->connect( @args) };
if ( $@ )
{
#DBI->connect threw an error via die
if ($@ =~ m/ORA-12154/i )
{
#handle this error, so I can clean up and continue
}
elsif ( $@ =~ m/SOME \s* other \s* ERROR \s+ string/ix )
{
#I can't handle this error, but I can translate it
die "our internal error code #7";
}
else
{
die $@; #re-throw the die
}
}
Есть некоторые незначительные проблемы с использованием eval таким образом, связанные с глобальной областью действия $ @. Страница Try :: Tiny cpan имеет отличное объяснение. Try :: Tiny выполняет минимальную настройку блока Try / catch и обрабатывает локализацию $ @ и обработку других крайних случаев.