[Madrid-pm] [RFC] Gestión de errores

Victor Moral victor en taquiones.net
Vie Mar 16 08:40:28 PDT 2007


El Viernes, 16 de Marzo de 2007 12:48, DervishD escribió:

>     He estado ojeando el libro y probablemente me lo compre en cuanto
> esté seguro de que mi mujer no me emasculará por comprar otro libro más
> de chorradas de ordenadores XDDD

	No es barato, desde luego, pero creo que merece la pena. 

>     En general, coincido bastante con la política de Conway de "ya sé
> que jode, pero las cosas hay que hacerlas bien". Lo que no quiere decir
> que esté de acuerdo con todo lo que dice en su libro, pero en lineas
> generales pensamos parecido.

	Pues a mí me ha tenido que demostrar mucho que tenía razón, y al final se la 
he dado cuando he tenido que afrontar aplicaciones grandes :-)

>     Bueno, lo del "isa()" se pasa un poco por el forro la encapsulación
> y no es buena práctica para un diseño orientado a objetos, en mi
> opinión, pero entiendo el mecanismo y personalmente también usaría isa()
> para gestionar, en lugar de hacer un framework que obligase al llamante
> a usar una implementación y diseños orientados a objeto. Es un buen
> compromiso usar "isa()".

	En realidad es fundamental para ello y no toca para nada la encapsulación. Si 
defines un conjunto de clases como estas:

use Exception::Class (
    'Impresor::X' => {
        isa         =>  'Basicos::Exceptions'
        },
    'Impresor::X::Config'   => {
        isa         =>  'Impresor::X',
        description =>  'Error in config file'
        },
    'Impresor::X::Config::File'  =>  {
        isa         =>  'Impresor::X::Config',
        description =>  'Config file not found or bad perms',
        fields      =>  [ qw(errno file) ]
        },
    'Impresor::X::Config::Template' => {
        isa         =>  'Impresor::X::Config',
        description =>  'Template file not found or bad perms',
        fields      =>  [ qw(errno file) ]
        },
    'Impresor::X::Config::Template::Format' =>  {
        isa         =>  'Impresor::X::Config::Template',
        description =>  'Invalid template format',
        fields      =>  [ qw(where) ]
        },
    'Impresor::X::Config::Content'  =>  {
        isa         =>  'Impresor::X::Config',
        description =>  'Malformed config file',
        fields      =>  [ qw(line) ]
        },
    'Impresor::X::Work::Queue'  => {
        isa         =>  'Impresor::X::Work',
        description =>  'Could not alloc new spool item',
        fields      =>  [ qw( queue ) ]
        },
    'Impresor::X::Work::Job' => {
        isa         =>  'Impresor::X::Work',
        description =>  'Missing job parameters in work definition'
        },
    'Impresor::X::Work::Job::Fields'    =>  {
        isa         =>  'Impresor::X::Work::Job',
        description =>  'Missing essential component in job definition',
        fields      =>  [ qw( component ) ]
        },
);

Puedes de un vistazo comprobar si el error tiene que ver con la configuración 
	
	my $ex = $@;
	if ($ex->isa('Impresor::X::Config')) {
		if ($ex->isa('Impresor::X::Config::File')) {
			# no existe el archivo de configuración, no importa, utilizamos 
			# los valores por defecto
			1;
		}
		else {
			# cualquier otra cosa es fatal: lanzamos hacia atrás
			$ex->rethrow();
		}
		...
ó con la gestión de trabajos 

	if ($@->isa('Impresor::X::Work')) {
		...

Exceptions::Class utiliza una función llamada caught() que simplifica un poco 
las cosas, porque si la excepción la ha provocado die() o croak() la 
convierte en un objeto Exception::Class antes de retornar. 

>     Nunca he usado Exception::Class, pero le echaré un ojo. Soy bastante
> reacio a usar módulos que no vengan en el core, así que (como soy un
> capullo y lo sé y no me importa) igual me escribo algo similar para
> colocarlo en mi Common.pm. Me gusta la abstracción de usar "throw" en
> lugar de "die", que me parece mucho más intuitivo aunque sea sólo un
> cambio de nombre. Y sí, ciertamente facilita la gestión de excepciones.

	Eso me pasaba a mí antes, que no quería utilizar nada que no viniese dentro 
de Perl, pero al final me he dado cuenta de que es un tanto absurdo no usar 
herramientas buenas y probadas. Lo que sí puede pasarte es que algo como "ví 
todo lo que había y nada me satisfizo" y, como dices, lo termines haciendo 
tú. :-)

>     Estoy acostumbrado a no usar depuradores paso a paso, suelo usar
> otras técnicas y sólo recurro al debugger cuando no puedo evitarlo.
> Además, se supone que gestionando los errores así deberías ahorrarte
> bugs...

	Bueno, más que ahorrarte errores los aislas y los tratas en zonas mucho más 
definidas que antes, que debías pasar hacia atrás un valor por ocho ó nueve 
capas de funciones. 

	Por cierto, ¿ has utilizado Smart::Comments ? Tengo unas notas sobre ello y 
es otro mecanismo que empiezo a usar mucho:

	http://taquiones.net/perl/cpan/smartcomments.html

>     Supongo que ningún código del que maneja excepciones de tu trabajo
> está bajo licencia GPL o similar ¿me equivoco? Es que estaría muy bien
> ver la propagación de excepciones en acción.

	Sí, te equivocas, lo único que no es público es el repositorio de subversion, 
pero los paquetes Debian están disponibles:

	http://www.venexma.net/debian/pool/main/i/impresor/

	Eso sí, éste tuvimos que hacerlo durante una emergencia y le falta muchísima 
documentación; tanta que estuve a punto de saltarme un ojo el otro día 
añadiéndole un listado.

>     Por cierto que hace un tiempo escribí un código de prueba para hacer
> excepciones en C, usando setjmp y longjmp, pero lo dejé porque aunque

	Uf, tiempo hace de eso. Era un mecanismo muy divertido para trabajar con él.

> funcionaba, había demasiados cabos sueltos, y es que intentar añadir
> semántica try/throw/catch al C es una locura. Al final lo hice a la
> forma C, con una librería de gestión de excepciones... que nunca terminé
> (¿he hablado ya del vicio que tengo de procastinar?, pues eso).

	¡ Qué me vas a contar ! Y antes todavía, pero ahora con la niña no hay 
manera :-)

Saludos 
-- 
 --------
 Víctor Moral <victor en taquiones.net>
 http://taquiones.net/victor.html
 Usuario Linux nº 139246

------------ próxima parte ------------
Se ha borrado un mensaje que no está en formato texto plano...
Nombre     : no disponible
Tipo       : application/pgp-signature
Tamaño     : 189 bytes
Descripción: no disponible
Url        : http://mail.pm.org/pipermail/madrid-pm/attachments/20070316/7b47c44c/attachment.bin 


Más información sobre la lista de distribución Madrid-pm