2009-07-23 4 views
2

Merci à tous d'avance.Catching errors with mod_cgi & mod_perl

J'ai fait des recherches sur la gestion des erreurs et je n'ai pas l'impression d'avoir une bonne compréhension de ce que je devrais faire. Préambule: Mon code réside dans Apache et est exécuté dans le navigateur. Mes objectifs n'incluent pas l'exécution de la ligne de commande. Je voudrais avoir le comportement de CGI :: Carp (fatalsToBrowser) avec la capacité de capturer la sortie et être capable de le lancer dans ma propre page de modèle, l'envoyer par courriel etc ... J'ai remarqué que fatalsToBrowser ne fonctionne pas avec mod_perl. Quelqu'un sait-il pourquoi? Comment Apache/mod_perl se met-il en travers?


Premier but: Je voudrais mettre quelque chose ensemble qui fonctionne si le code est en cours d'exécution avec mod_perl ou mod_cgi.

Deuxième objectif: J'aimerais disposer d'une ou plusieurs méthodes de haut niveau qui capturent toutes les erreurs similaires à Application_Error de .NET (dans global.asax) et aux méthodes set_exception_handler() et set_error_handler() de PHP. Ceux-ci vous permettent de prendre le contrôle quand une erreur est soulevée, sans encapsuler le code /gross instructions try-catch.


choses que j'ai lu/examiné:

1.) OO Exception Handling in Perl, mais n'a pas été ce que je cherchais. La plupart des choses que je veux attraper est die() ing. Le lien suivant dit aussi que cet article est obsolète et obsolète.

2.) Perl: $SIG{__DIE__}, eval { } and stack trace, mais je n'ai pas eu beaucoup de choses liées à mes objectifs.

3.) Mode pratique Perl (O'Reilly), chapitre 21 "Traitement d'erreur et mise au point". Heureusement, tout mon code perl utilise strict et les avertissements sont activés, et les choses les plus importantes mentionnées au chapitre 6 "Coder avec mod_perl in Mind" sont déjà effectuées. 4. J'ai exploré les tables des matières dans "Learning Perl", "Perl Cookbook", "Programming Perl" et "Higher Order Perl" et je n'ai rien vu qui me soit apparu. Si vous pensez que j'ai raté quelque chose s'il vous plaît faites le moi savoir. :)


Je ne me souviens pas où (peut-être dans « mod_perl pratique », mais je l'ai lu que vous ne devriez pas jouer avec $ SIG {__ DIE__}.

+0

Vos scripts sont-ils de véritables scripts 'mod_perl' ou vous exécutez simplement des scripts CGI en tant que scripts' ModPerl :: Registry' pour l'avantage de la performance? –

+0

Mes scripts doivent (devraient) effectuer la même chose dans les deux environnements. – rakhavan

+0

Je pense que vous devriez réévaluer votre opinion sur try/catch blocks. Ils ne sont pas du tout désordonnés ou grossiers s'ils sont utilisés au bon niveau. – innaM

Répondre

1

Avez-vous lu le bit du site mod_perl sur Alternative Exception Handling Techniques? Il explique comment vous pouvez intercepter les exceptions non interceptées en utilisant la fonction globale die() au lieu d'utiliser $SIG{__DIE__}. Une méthode beaucoup plus propre mais pas parfaite.

+0

Merci une tonne! C'était une bonne lecture. – rakhavan

+0

Je suis content que je puisse vous aider. – Weegee

1

Quel type d'erreurs sont vous ? essayer de capture sont custom error pages ne suffit pas à vos fins

Mes scripts CGI sont courts (OK, ce qui est vraiment os nus — et non testé):

#!/usr/bin/perl 

use strict; 
use warnings; 

use My::App; 
use My::ErrorReporter qw(error_to_html); 

run(); 

sub run { 
    my $app = eval { 
     My::App->new(
      'some_param', 
      'another_param', 
     ) 
    }; 

    unless ($app) { 
     print error_to_html([email protected]); 
     return; 
    } 

    eval { 
     $app->handle_request;   
    } and return; 

    print error_to_html([email protected]); 
    return; 
} 

__END__ 

Maintenant, fatalsToBrowser n'est pas pour vos utilisateurs. C'est une aide au développement pour vous. Les messages d'erreur que les utilisateurs voient ne doivent pas transmettre d'informations sur le programme.Ainsi, par exemple, dans une routine qui ouvre et lit un fichier de configuration, vous devez faire quelque chose comme:

sub read_my_config { 
    my $self = shift; 

    open my $config_h, '<', $self->config_file; 

    unless ($config_h) { 
     # This goes to the Apache error log where you can read it 
     warn sprintf(
      "Cannot open '%s': %s", 
      $self->config_file, $! 
     ); 
     # This is for web site visitors to see 
     die "Cannot open configuration file"; 
    } 

    # rest of the code 
} 
+0

J'autorise le programmeur à choisir s'il veut que le stackstrace apparaisse dans le message d'erreur ... évidemment dans l'environnement de production nous désactiverions la trace de pile affichée. Cependant je voudrais toujours y avoir accès afin que je puisse montrer à l'utilisateur un message amical et envoyer un e-mail à l'administrateur le vrai stacktrace ou l'enregistrer sur le db etc ... Veuillez voir mon second objectif dans mon OP, je ne sais pas Je veux tout emballé dans un essai/attraper ... J'ai besoin d'un receveur d'erreurs de haut niveau qui peut prendre le contrôle de leur information appropriée. – rakhavan

+0

Cela vous semble-t-il désordonné/grossier? – innaM

+0

Oui/Non ... Je pense que @Weegee m'a donné ce que je cherchais. J'ai besoin de quelque chose qui n'est pas connecté au (x) script (s) pour piéger les erreurs globales dans mes applications. Je vais voir si cela fonctionne avant de choisir une réponse. Encore merci pour vos réponses, très appréciées. – rakhavan