Excepcion propia con codigo interno

04/07/2007 - 13:19 por ANT1 | Informe spam
Hola a todos, estaba interesado en crear una excepcion propia para
gestionar las excepciones o alertas que se podrian dar en mi app (que
un NIF de cliente se duplque o que no tenga el formato correcto y
demas).

En principio pense en usar la propia Excpetion o ApplicationException
al ver que tenian la propiedad Data (un idictionary), pero he visto
que esta propiedad solo dispone de metodo Get, no Set. ¿existe alguna
excepcion que se pueda modificar con algun parametro del estilo?, es
decir, una propiedad a la que pueda dar yo un valor para despues
recuperar y dependiendo de ese valor sacar una ventana de informacion
u otra (es para algo mas complejo que sacar solo el mensaje de error).

Habia pensado en algo asi:

public class ExceptionMia:ApplicationException

struct Mensaje
{
string titulo, alerta, mensaje;
image icono;
public Mensaje(string t, string a, string m, imagen i){ titulo = t;
alerta = a; mensaje = m; icono = i; }
}

Dictionary<int, Mensaje> Errores = new Dictionary>in, Mensaje>();
// Aqui llenaria los mensajes que me interesasen en el dictionary, por
ejemplo:
Errores.Add(0,"Error 0","Error En NIF", "El NIF introduccido no es
correcto, por favor revise su valor",
global::aplicacion.Properties.Resources.alerta);
Errores.Add(1,"Error 1","Error Cualquiera","Este es un error
cualquiera que se me
ocurre",global::aplicacion.Properties.Resources.error1);
// ... asi con todos los errores que desee ir añadiendo


private string titulo;

public string Titulo
{
set { titulo= value; }
get { return titulo; }
}

private string alerta;

public string Alerta
{
set { alerta= value; }
get { return alerta; }
}

private string mensaje;

public string Mensaje
{
set { mensaje = value; }
get { return mensaje; }
}


private image imagen;

public image Imagen
{
set { imagen = value; }
get { return imagen; }
}

public ExceptionMia(int codigo):base(null)
{
Mensaje aux = Mensajes[codigo];
this.Titulo = aux.titulo;
this.Alerta = aux.alerta;
this.Mensaje = aux.mensaje;
this.Imagen = aux.icono;
}

public ExceptionMia(int codigo, Exception innere):base(null, innere)
{
Mensaje aux = Mensajes[codigo];
this.Titulo = aux.titulo;
this.Alerta = aux.alerta;
this.Mensaje = aux.mensaje;
this.Imagen = aux.icono;
}

Me gustaria saber vuestra opinion, sobre todo porque no me gusta en
exceso, y no se si funcionaria, la parte del diccionario.

Un saludo.

Preguntas similare

Leer las respuestas

#6 ANT1
04/07/2007 - 17:49 | Informe spam
No tienes por qué añadir un nuevo diccionario, puedes simplemente añadir
un dato miembro de tu estructura, te defines un constructor de copia para
la misma y listo.



Me temo que no termino de entender esto que comentas.

O si el icono es un icono de error de una serie predefinida, defines un
array de iconos estáticos a tu excepción (mejor a la clase más base de tu
jerarquía de excepciones), y sólo tienes que pasar el índice del icono,
ahorrando una buena espuerta de memoria.



Esta misma idea (y teniendo en cuenta que no entendi el parrafo
anterior) me gusta para hacer un array de la estructura que defini, en
lugar de un diccionario, ya que al ser el codigo un entero puedo
usarlo como indice directamente.

Ahora, lo que no tengo tan claro es lo correcto que pueda ser elevar una
excepción porque un DNI esté duplicado, etc. Más bien eso creo (y sólo
creo, ya me meto en aguas que desconozco) que debería hacerlo el gestor de
bases de datos.

Yo personalmente, ante una situación como la que presentas no elevaría una
excepción (que son caras en tiempo de ejecución, no el disparo ni el
bloque try, sino la captura y elevación), sino que daría un mensaje de
error y dejaría reintentar o algo así. Pero ya te digo que esto
simplemente es una opinión.



Yo hasta ahora este tipo de "errores" los contemplaba el el form de
edicion relacionado. Comprobaba que todo fuese correcto y si no lo era
sacaba una ventena propia de error (que necesita icono, titulo, alerta
y mensaje. De ahi la estructura). Esto me parecia lo correcto, ya que
mediante un if (si era correcto o no) sacaba o no dichos errores.

Pero me han solicitado que este tipo de errores sean controlados
totalmente por la clases de mi proyecto (cliente, curriulcum,...) en
lugar desde el form para que de ser reutilizado mi assembly de datos
para otra app o una a aplicacion web, no sea necesario volver a
escribir todo ese codigo, ay que la propia clase antes de hacer un
update, delete o create verifica los filtros y de no ser correcto el
resultado lanza una excepcion, encargandose de su recepcion el form y
actuando en consecuencia (en este caso sacando por pantalla el error).

No me termina de agradar dicha forma de trabajo a mi tampoco, pero es
lo que me han solicitado y por tanto procuro hacerlo lo mejor que
pueda.

Un saludo
Respuesta Responder a este mensaje
#7 RFOG
04/07/2007 - 18:08 | Informe spam
En Wed, 04 Jul 2007 17:49:59 +0200, ANT1 escribió:

No tienes por qué añadir un nuevo diccionario, puedes simplemente añadir
un dato miembro de tu estructura, te defines un constructor de copia
para
la misma y listo.



Me temo que no termino de entender esto que comentas.



Tu tienes una estructura que llamas Mensaje. Pues haz algo así:

class MiExcepcion:Exception
{
private Mensaje m_mensaje;
...
};

Cuando vayas a lanzar la excapción, en el constructor de la excepción,
pasas los valores que te interesen de tu estructura.

Para asigunar una estructura sobre otra, es decir:

Mensajse m=otroMensaje;

Necesitas que la estructura implemente un constructor de copia a riesgo de
no copiar manejadores y cadenas etc en profundidad...



O si el icono es un icono de error de una serie predefinida, defines un
array de iconos estáticos a tu excepción (mejor a la clase más base de
tu
jerarquía de excepciones), y sólo tienes que pasar el índice del icono,
ahorrando una buena espuerta de memoria.



Esta misma idea (y teniendo en cuenta que no entendi el parrafo
anterior) me gusta para hacer un array de la estructura que defini, en
lugar de un diccionario, ya que al ser el codigo un entero puedo
usarlo como indice directamente.




A ver, tu pasas a tu estructura un icono, que imagino será un bitmap
representando dicho icono. Si cada vez que lances una excepción, has de
instanciar y copiar un icono, estás liándola un poco (no es que sea
técnicamente incorrecto, sino que simplemente es ineficiente).

Por lo tanto, si tienes la lista de bitmas como un array estático de la
excepción base, solamente se asignará memoria para los gráficos una vez, y
será de ahí de donde todas las clases hijas tomen el icono correspondiente
y lo saquen por pantalla.

Es decir:

class ExcepcionBase:Exception
{
protected static Bitmap[] iconos;
...
};

class ExcepcionHija:ExcepcionBase
{
public ExcepcionHija(int iIcono)
{
m_iIcon=iIcono;
};
}

A la hora de pintar el icono, te referirás a iconos[m_iIcon] y no tendrás
que pasar en los constructores ni en ningún lado más los gráficos,
solamente en el constructor estático de la clase base, que asignará la
memoria.

Y mejor aún: el índice al icono podría ser una enumeración, así evitas
salirte de rango:

enum IconosError:int
{
Error1=0,
Error2=1,
ErrorExtraño=3
}

Y luego, cuando te refieras a iconos[m_iICon] lo haces mediante
iconos[(int)m_icon], siendo m_icon una variable de la enumeración
superior. Así, nunca podrás salirte de rango en el índice.

Ahora, lo que no tengo tan claro es lo correcto que pueda ser elevar una
excepción porque un DNI esté duplicado, etc. Más bien eso creo (y sólo
creo, ya me meto en aguas que desconozco) que debería hacerlo el gestor
de
bases de datos.

Yo personalmente, ante una situación como la que presentas no elevaría
una
excepción (que son caras en tiempo de ejecución, no el disparo ni el
bloque try, sino la captura y elevación), sino que daría un mensaje de
error y dejaría reintentar o algo así. Pero ya te digo que esto
simplemente es una opinión.



Yo hasta ahora este tipo de "errores" los contemplaba el el form de
edicion relacionado. Comprobaba que todo fuese correcto y si no lo era
sacaba una ventena propia de error (que necesita icono, titulo, alerta
y mensaje. De ahi la estructura). Esto me parecia lo correcto, ya que
mediante un if (si era correcto o no) sacaba o no dichos errores.

Pero me han solicitado que este tipo de errores sean controlados
totalmente por la clases de mi proyecto (cliente, curriulcum,...) en
lugar desde el form para que de ser reutilizado mi assembly de datos
para otra app o una a aplicacion web, no sea necesario volver a
escribir todo ese codigo, ay que la propia clase antes de hacer un
update, delete o create verifica los filtros y de no ser correcto el
resultado lanza una excepcion, encargandose de su recepcion el form y
actuando en consecuencia (en este caso sacando por pantalla el error).




¿Y no sería mejor tener una clase estática a la que llames para mostar el
error? Es decir, como MessageBox.Show(), pues MisErrores.Show().


No me termina de agradar dicha forma de trabajo a mi tampoco, pero es
lo que me han solicitado y por tanto procuro hacerlo lo mejor que
pueda.

Un saludo






Visita mi blog principal: http://rfog.blogsome.com
Y este sobre programación: http://geeks.ms/blogs/rfog
Libros, ciencia ficción y programación
Cacarear y no poner huevos, cada día lo vemos.
Respuesta Responder a este mensaje
#8 RFOG
04/07/2007 - 18:18 | Informe spam
En Wed, 04 Jul 2007 17:49:59 +0200, ANT1 escribió:

Yo hasta ahora este tipo de "errores" los contemplaba el el form de
edicion relacionado. Comprobaba que todo fuese correcto y si no lo era
sacaba una ventena propia de error (que necesita icono, titulo, alerta
y mensaje. De ahi la estructura). Esto me parecia lo correcto, ya que
mediante un if (si era correcto o no) sacaba o no dichos errores.

Pero me han solicitado que este tipo de errores sean controlados
totalmente por la clases de mi proyecto (cliente, curriulcum,...) en
lugar desde el form para que de ser reutilizado mi assembly de datos
para otra app o una a aplicacion web, no sea necesario volver a
escribir todo ese codigo, ay que la propia clase antes de hacer un
update, delete o create verifica los filtros y de no ser correcto el
resultado lanza una excepcion, encargandose de su recepcion el form y
actuando en consecuencia (en este caso sacando por pantalla el error).

No me termina de agradar dicha forma de trabajo a mi tampoco, pero es
lo que me han solicitado y por tanto procuro hacerlo lo mejor que
pueda.

Un saludo



En todo esto veo un error bastante serio (supongo que no lo será porque se
me esté escapando algo).

A ver, tienes el botón de guardar los datos de tu ficha:

void btnGuardarClick(...)
{
if(datosMal)
trhow new MiExcepcion(bla bla bla);
}

¿Cómo vuelves de la excepción a la ficha?

Sin embargo, así:

void btnGuardarClick(...)
{
if(datosMal)
MensajesError.Show(bla bla bla);
}

Y sigues en la ficha.

De todos modos, en ambos casos, en la ficha tienes que comprobar las
condiciones, y si son incorrectas, lanzar la excepción, que es lo mismo
que comprobar las condiciones y mostrar un mensaje de error.


Visita mi blog principal: http://rfog.blogsome.com
Y este sobre programación: http://geeks.ms/blogs/rfog
Libros, ciencia ficción y programación
Cacarear y no poner huevos, cada día lo vemos.
Respuesta Responder a este mensaje
#9 Alberto Poblacion
04/07/2007 - 22:27 | Informe spam
"ANT1" wrote in message
news:
La verdad es que esta solucion me gusta mas que la anterior ya que no
hay que repetir propiedades ni nada por el estilo.



Sí, yo también creo que queda más limpia que la anterior.

Lo unico que no me
gusta es tener definido un diccionario que podria ser enorme
(imaginemos que mi aplicacion creciese hasta 50 excepciones propias)
para lugo no utilizar mas que un conjunto de valores de estos.
No veo claro que esto sea lo mas adecuado.
¿Que opinais?



Bueno, yo me inspiraría en el SqlException que usa Microsoft para
devolver los errores en las llamadas a Sql Server, que tiene unos requisitos
similares a los tuyos: Tiene una serie de propiedades tales como código del
error, mensaje, severidad, etc., y tiene un diccionario de errores muy
grande porque son muchos los errores que puede devolver el Sql Server. La
cuestión es que el diccionario de errores no está dentro de la clase
SqlException, sino dentro del proceso que lanza las excepciones (en este
caso vienen de Sql Server). De esta forma, la clase en sí no es muy
compleja, y el proceso que lanza las excepciones, que es el que en cualquier
caso tiene que conocerlas, es el que tiene el diccionario, y símplemente
copia los valores a la excepción en el momento de construirla.
Respuesta Responder a este mensaje
#10 ANT1
12/07/2007 - 09:56 | Informe spam
Ante todo hola de nuevo. Siento el paron de estos dias pero, se
estropeo mi ordenador y he andado montando uno nuevo y volviendo a
instalar y recuperar todos mis datos.

Retomo el hilo donde se quedo.

A ver, tu pasas a tu estructura un icono, que imagino será un bitmap
representando dicho icono. Si cada vez que lances una excepción, has de
instanciar y copiar un icono, estás liándola un poco (no es que sea
técnicamente incorrecto, sino que simplemente es ineficiente).

Por lo tanto, si tienes la lista de bitmas como un array estático de la
excepción base, solamente se asignará memoria para los gráficos una vez, y
será de ahí de donde todas las clases hijas tomen el icono correspondiente
y lo saquen por pantalla.

Es decir:

class ExcepcionBase:Exception
{
protected static Bitmap[] iconos;
...

};

class ExcepcionHija:ExcepcionBase
{
public ExcepcionHija(int iIcono)
{
m_iIcon=iIcono;

};
}

A la hora de pintar el icono, te referirás a iconos[m_iIcon] y no tendrás
que pasar en los constructores ni en ningún lado más los gráficos,
solamente en el constructor estático de la clase base, que asignará la
memoria.

Y mejor aún: el índice al icono podría ser una enumeración, así evitas
salirte de rango:

enum IconosError:int
{
Error1=0,
Error2=1,
ErrorExtraño=3

}

Y luego, cuando te refieras a iconos[m_iICon] lo haces mediante
iconos[(int)m_icon], siendo m_icon una variable de la enumeración
superior. Así, nunca podrás salirte de rango en el índice.



Algo como lo que comentas es mi intencion hacer. Lo de la clase base
de la excepcion donde almacene estaticamente los valores dependiendo
del codigo de excepcion mio me parece una buena idea. No se me habia
ocurrido de esta manaera. Yo ahora estaba planteandome hacer
practicamente lo mismo pero con dos clases sin que se heredaran la una
de la otra, pero tu idea me gusta mas.

El problema que tengo es que no termino de ver como definir la
coleccion de errores propios estaticamente, y esto es por falta de
conocimiento y experiencia en la programacion. Yo a la hora de definir
una propiedad static en una clase siempre era algo sencillo, estilo a:

public static int ValorCualquiera = 0;

Donde se le define el valor facilmente. Pero en el caso de la
coleccion no termino de ver como definirla. En el constructor no, ya
que ahi solo se crearian los valores al crear una instancia de la
clase ¿verdad?. Pero no termino de ver como definir los distintos
elementos que componen este. ¿Se puede escribr codigo tal que asi?

class ExcepcionP:Exception
{
private Dictionary<int, Mensaje> diccionario = new
Dictionary<int, Mensaje>();
// Mensaje era la estructura mia
diccionario.Add(0, "titulo0","alerta0","mensaje0",imagen0);
diccionario.Add(1, "titulo1","alerta1","mensaje1",imagen1);
...
}

¿Como si no añado todos los posibles valores a mi diccionario?

¿Y no sería mejor tener una clase estática a la que llames para mostar el
error? Es decir, como MessageBox.Show(), pues MisErrores.Show().



Tengo un formulario (una ventana estilo MessageBox) a la que pasandole
los parametros de mi estructura muestra el error correspondiente. A
esta la llamaria una vez recogida la excepcion lanzada.

Un saludo
Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaSiguiente AnteriorRespuesta Tengo una respuesta
Search Busqueda sugerida