Pregunta

Estoy jugando un poco con el control de errores y consiguió un pequeño problema. Conecto con una base de datos utilizando el módulo DBI.

Yo hago mi propia gestión de errores mediante el uso de una subrutina que hago un llamado a un error.

Me puede coger mis propios moldes y manejarlos muy bien, pero cuando mi conexión de base de datos falla, el módulo DBI aparentemente imprime su propio morir:

  

DBI connect (...) falló: ORA-12154: TNS: no podía resolver el       identificador de la conexión especificado (DBD ERROR: OCIServerAttach) a las ...

¿Cómo hago para coger esto?

He intentado utilizar $SIG{__DIE__} este modo:

local $SIG{__DIE__} = sub {
  my $e = shift;
  print "Error: " .$e;
};

Esto es en el fondo de mi archivo principal, en este archivo Yo también llamar la subrutina de conexión que está disponible en un módulo de la mía. También he intentado poner este pedazo de código en la parte inferior de mi módulo pero todavía imprime el error sin el

  

Error:

delante de él.

¿Fue útil?

Solución 2

De acuerdo, encontrado la solución, al parecer necesitaba __WARN__ en lugar de __DIE__ y este pedazo de código necesario para estar en la parte superior del archivo, antes de donde se lanzó el error, a diferencia del ejemplo que leí declaró:)

Otros consejos

  

DBI connect (...) falló: ORA-12154:   TNS: no podía resolver la conexión   identificador especificado (DBD ERROR:   OCIServerAttach) a las ...

     

¿Cómo hago para coger esto?

Para capturar y manejar este nivel de error, el uso de eval en forma de bloque, "eval {...}". Esto cogerá cualquier matriz que ocurre en el sub código. Si el código dentro de un bloque eval matrices, fijará $ @ y el bloque volverá falsa. Si el código no muere, $ @ se establecerá en ''.

El uso de manejo de señales a través de SIG {} WARN y SIG {} DIE es problemático, ya que son globales, también hay que considerar las condiciones de carrera (lo que sucede si recibo una señal mientras estoy manejando una señal diferente? Etc. temas tradicionales de la informática basada en la señal). Probablemente se esté escribiendo código de un solo subproceso, por lo que no está preocupado por los problemas de concurrencia de varias cosas que llaman la matriz, pero no es el usuario a tener en cuenta (tal vez que va a enviar un SIGKILL mientras que usted está tratando de abrir la conexión DBI )

En este caso específico, está utilizando DBI. Con DBI, se puede controlar lo que sucede en el caso de error, si debe morir, advertir, o fracasar en silencio y esperar a que compruebe el estado de retorno.

Este es un ejemplo básico de usar 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
    }
}

Hay algunos problemas menores con el uso de eval esta manera, tener que ver con el alcance global de $ @. El href="https://metacpan.org/pod/Try::Tiny" rel="nofollow noreferrer"> Trate :: Tiny página CPAN tiene una gran explicación. Trate :: asas Diminuto una configuración mínima try / catch bloque y manijas de localización $ @ y gastos de los otros casos extremos.

Incluir esto en su bloque SIG{__DIE__}:

### Check if exceptions being caught.
return if $^S;

Esto evitará que su manejador de ser utilizado en código basado en excepción de que genera una matriz dentro de un bloque eval.

Esto no es tan genérico como un colector general mueren, pero específicamente para el manejo de error DBI en realidad tenemos nuestro propio módulo, de envolturas alrededor de las llamadas bases de datos; y una de las funcionalidades del módulo es envolver eval (dependiendo de una bandera) alrededor de cada llamada DBI.

Esto nos permite hacer el manejo de error personalizado en el nivel de acceso a datos, tales como reintentos de consulta, estadísticas, failover automatizado y más -. Todo transparente para el resto del código

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top