Perl: ручка умирает перед рамками - PullRequest
0 голосов
/ 29 января 2012

Я работаю с perl-фреймворком, который отслеживает сам $ SIG { DIE }, мой код был выполнен фреймворком, поэтому мой код дескриптора исключения не может быть выполнен, потому что фреймворк первым обнаружилисключение, а затем прекратить выполнение сценария.

frame.pm

sub execute
{
  $SIG{__DIE__}         = \&_handleDie;

  eval{  #execute myscript.pl sub main  
         $rv = &$pFunct(@args);}

  if ($@){ processException($@)}

  print "myscript.pl success executed"           

}

myscript.pl

use frame;
frame->execute( \&main );

sub main
{ 
   %codes that redirect STDOUT to a file% 

   #if below API cmd no exception, hide it's output, 
   #otherwise output the API cmd STDERR msg

   %codes called API of another module%


   try
    {
        die("sth wrong");
    }catch{
        %codes restore STDOUT to terminal% 
        print "error msg, but this line will not be executed, how to get it be execute?"
    }
}

Сценарий сначала перенаправляет STDOUT в файл для некоторых не используемых выводов.

Когда я хочу реализовать, если произойдет исключение (линия высечки), сценарий может восстановить STDOUT на терминал, а затем вывести ошибку на терминал.Теперь он обрабатывается кадрами и печатается в STDOUT, но не в STDERR, поэтому мне нужно обработать восстановление STDOUT, прежде чем печатать его в STDOUT.

с помощью решения ruakh, myscript.pl прошел SIG кадра, теперь перехватывается SIGстрока кадра if ($ @) {processException ($ @)}, , то есть когда выполняется myscript-> die (), программа переходит в frame-> if ($ @) {processException ($ @)}, ноне myscript-> catch

=====================

Я наконец нашел это работает для меня:

myscript.pl

frame->execute( \&main );

sub main
{
    open my $stdOri, ">&STDOUT";
    my $tmpFile = "/tmp/.output.txt.$$";
    open STDOUT, ">$tmpFile";

    #overwrite frame provided exception handling.
    local $SIG{__DIE__}=sub{close STDOUT;  open STDOUT, ">&", $stdOri;};

    #cause a exception, 
    #this exception will be processed by 'local $SIG{__DIE__}' block which restore STDOUT
    #then frame->eval catch this exception, and print it in the terminal.
    my $c=5/0;

}

спасибо за вдохновение Руаха.

Ответы [ 2 ]

1 голос
/ 30 января 2012

Обработчик $SIG{__DIE__} фреймворка неверный, неправильный, неправильный. Он не должен есть исключения внутри eval. Это должно сделать die @_ if $^S, как предложено perldoc -f die .

1 голос
/ 29 января 2012

Предполагая, что вы не хотите изменять каркас, вы можете локально переопределить обработчик сигнала:

use frame;
frame->execute( \&main );

sub main
{
   try
    {
        local $SIG{__DIE__}; # remove signal-handler
        die("sth wrong");
    }catch{
        print STDERR "error msg";
        die $@; # pass control back to framework's signal handler
    }
}

Отказ от ответственности: протестировано с eval -блоком, а не с try/ catch, поскольку у меня не установлено TryCatch.Насколько я понимаю, TryCatch зависит от eval, а не от $SIG{__DIE__}, но я могу ошибаться.

...