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

#11 ANT1
12/07/2007 - 10:02 | Informe spam
On 4 jul, 18:18, RFOG wrote:
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?



La excepcion no la lanzo desde la ficha, si te refieres con "ficha" al
formularioque se muestra por pantalla. Estas excepciones las lanzo
desde las clases mapeadas a mi base de datos. En lo metodos Save,
Delete,... hago una serie de comprobaciones pertinentes y si hay algun
error lanzo la excepcion que es recogida por el formulario que
solicito el Save de alguna de dichas clases y el que se encargaria de
mostrar por pantalla el error (ya sea mediante messagebox o mediante
el formulario mio que te comentaba en el comentario anterior).

Sin embargo, así:

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

}

Y sigues en la ficha.



Hasta ahora trabajaba asi, pero me han pedido que sea la clase mapeada
la que se encargue de realizar las comparaciones (el "if(datosMal)").
Por lo visto quieren que sea la clase la que se encargue de
practicamente todo, para poder migrar si fuese necesario despues dicha
clase a una app web o a otra app sin tener que copiar codigo de los
formularios que se muestran por pantalla.
Respuesta Responder a este mensaje
#12 ANT1
12/07/2007 - 10:11 | Informe spam
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.



Habia pensado en lo que comentaba con RFOG. Poner el Diccionario en
otra clase de manera estatica, y con su comentario ponerlo en una
clase ExcepcionBase.

El problema como comento antes es como definir los valores a dicho
diccionario. No termino de verlo, y seguramente es porque nunca habia
estado en esta situacion a la hora de programar.

Si se te ocurre algo...

Un saludo
Respuesta Responder a este mensaje
#13 RFOG
12/07/2007 - 10:24 | Informe spam

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?




En C++/CLI existe el constructor estático, que debe ser privado y
estático; en C# supongo que sería así:

class c
{
private static int[] enteros;
private static c()
{
enteros=new int[3] {1,2,3};
}
public c()
{
...
}

Ese constructor se llama únicamente una sola vez en el primer acceso a
cualquier objeto de dicha clase, y su única función es la de inicializar
las variables estáticas complejas (o una forma de juntar todas las
inicializaciones estáticas y no tenerlas desperdigadas por toda la
definición de la clase), y, en determinadas situaciones, es la única forma
de construir objetos complejos estáticos.

Ahí es donde debes inicializar la lista de bitmaps y/o lo que quieras.

¿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.




Ya. Algo así:

void BotonGuardarEvent()
{
if(ALGO_MAL)
throw new MiExcepcion(tipoError,bla,bla)
else
Graba();
}

Una vez que estás en la excepción, ¿cómo vuelves al manejador del botón?

¿No sería mejor algo así?:

void BotonGuardarEvent()
{
if(ALGO_MAL)
MiMensaje.Muestra(tipoError,bla, bla)
}
else
Graba();
}

Es lo mismo, exactamente lo mismo, pero con la ventaja de que sigues en la
ficha.

Con el código de arriba, una vez que has lanzado la excepción, ésta ser
recoge en el bloque catch más cercano, y ya no puedes volver a la ficha, a
no ser que uses algo así:

void BotonGuardarEvent()
{
try
{
if(ALGO_MAL)
throw new MiExcepcion(tipoError,bla,bla)
else
Graba();
}catch(MiExcepcion e)
{
...
}
}

Que no sé si funcionará (es decir el bloque catch te cogería la excepción
lanzada arriba, o será un catch superior el que lo haga), y si funcionara
sería, IMHO, una tontería como un castillo, mucho código, mucho tiempo de
ejecución para nada. Recuerda la Navaja de Occam: lo más sencillo es
siempre lo mejor.

Quizás se me escape algo, pero lo veo así.



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
Hay que escuchar a la razón, pero dejar hablar al sentimiento.
Respuesta Responder a este mensaje
#14 RFOG
12/07/2007 - 10:26 | Informe spam
Vale. Ahora sí que lo entiendo.

No hagas caso de la última parte de mi mensaje anterior.

En Thu, 12 Jul 2007 10:02:31 +0200, ANT1 escribió:

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



La excepcion no la lanzo desde la ficha, si te refieres con "ficha" al
formularioque se muestra por pantalla. Estas excepciones las lanzo
desde las clases mapeadas a mi base de datos. En lo metodos Save,
Delete,... hago una serie de comprobaciones pertinentes y si hay algun
error lanzo la excepcion que es recogida por el formulario que
solicito el Save de alguna de dichas clases y el que se encargaria de
mostrar por pantalla el error (ya sea mediante messagebox o mediante
el formulario mio que te comentaba en el comentario anterior).

Sin embargo, así:

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

}

Y sigues en la ficha.



Hasta ahora trabajaba asi, pero me han pedido que sea la clase mapeada
la que se encargue de realizar las comparaciones (el "if(datosMal)").
Por lo visto quieren que sea la clase la que se encargue de
practicamente todo, para poder migrar si fuese necesario despues dicha
clase a una app web o a otra app sin tener que copiar codigo de los
formularios que se muestran por pantalla.






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
Hay que escuchar a la razón, pero dejar hablar al sentimiento.
Respuesta Responder a este mensaje
#15 ANT1
12/07/2007 - 11:33 | Informe spam
En C++/CLI existe el constructor estático, que debe ser privado y
estático; en C# supongo que sería así:

class c
{
private static int[] enteros;
private static c()
{
enteros=new int[3] {1,2,3};}

public c()
{
...

}

Ese constructor se llama únicamente una sola vez en el primer acceso a
cualquier objeto de dicha clase, y su única función es la de inicializar
las variables estáticas complejas (o una forma de juntar todas las
inicializaciones estáticas y no tenerlas desperdigadas por toda la
definición de la clase), y, en determinadas situaciones, es la única forma
de construir objetos complejos estáticos.

Ahí es donde debes inicializar la lista de bitmaps y/o lo que quieras.



No termino de comprenderlo yo ahora.

¿Seria necesario dentro del constuctor publico llamar al constructor
estatico?¿o es que se llama automaticamente, como comentas, en cuanto
se hace referencia a dicha clase?
Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaSiguiente AnteriorRespuesta Tengo una respuesta
Search Busqueda sugerida