elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Introducción a la Factorización De Semiprimos (RSA)


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  Java
| | | |-+  varios try catch en un mismo código
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: varios try catch en un mismo código  (Leído 1,788 veces)
juligarc10

Desconectado Desconectado

Mensajes: 47


Ver Perfil
varios try catch en un mismo código
« en: 19 Febrero 2019, 11:43 am »

Hola amigos. Tengo un problema.
Estoy intentando diseñar un código en el cual se recojan las exceptiones con try catch, pero a la vez que las recojo, si estas excepciones aparecen, deberá de pedirse otra vez el código con un do while hasta que lo introducido sea correcto. Me explico:

Código:
do{
            try{
        System.out.print("Nombre del cliente ");
        if (c.getNombre().length() > 0) {
            System.out.print("[" + c.getNombre() + "]");
        }
       
       
        System.out.print(": ");
        info = teclado.nextLine().trim();
        if (info.length()<=0||isNumeric(info)==true){
            throw new Exception("Debe introducir un nombre");
        }
       
            }catch(Exception exc){
                System.err.println( "ERROR:\n "+exc.getMessage());
            }
        }while(info.length()<=0||isNumeric(info)==true);

        if (info.length() > 0) {
            c.setNombre(info);
        }

        // D.N.I.
        do{
        try{
        System.out.print("D.N.I. del cliente ");
        if (c.getDni().length() > 0) {
            System.out.print("[" + c.getDni() + "]");
        }
        System.out.print(": ");
        info = teclado.nextLine().trim();
        if (info.length()<=0||isNumeric(info)==false){
            throw new Exception("Debe introducir un dni");
        }
        }catch(Exception e){
            System.err.println("ERROR:\n "+e.getMessage());
        }
        if (info.length() > 0) {
            c.setDni(info);
        }
        while(info.length()<=0||isNumeric(info)==false);

       

Mi idea es hacerlo realizando varios try, cada uno dentro de su do/while. No se me ocurre otra manera de hacerlo más óptimo. ¿La hay?
El otro problema es que el código, haciéndolo de esta manera no me funciona. Las excepciones las recoge bien, pero una vez le metes un código que en teoría es válido, lanza una excepcion llamada "java.lang.RuntimeException: Uncompilable source code".
El tema es que si yo solo tengo habilitado un try catch, el código si funciona perfectamente, así:
Código:
// Nombre
        do{
            try{
        System.out.print("Nombre del cliente ");
        if (c.getNombre().length() > 0) {
            System.out.print("[" + c.getNombre() + "]");
        }
       
       
        System.out.print(": ");
        info = teclado.nextLine().trim();
        if (info.length()<=0||isNumeric(info)==true){
            throw new Exception("Debe introducir un nombre");
        }
       
            }catch(Exception exc){
                System.err.println( "ERROR:\n "+exc.getMessage());
            }
        }while(info.length()<=0||isNumeric(info)==true);

        if (info.length() > 0) {
            c.setNombre(info);
        }

        // D.N.I.
        /*do{
        try{
        System.out.print("D.N.I. del cliente ");
        if (c.getDni().length() > 0) {
            System.out.print("[" + c.getDni() + "]");
        }
        System.out.print(": ");
        info = teclado.nextLine().trim();
        if (info.length()<=0||isNumeric(info)==false){
            throw new Exception("Debe introducir un dni");
        }
        }catch(Exception e){
            System.err.println("ERROR:\n "+e.getMessage());
        }
        if (info.length() > 0) {
            c.setDni(info);
        }
        while(info.length()<=0||isNumeric(info)==false);*/

¿Alguna idea gente? Gracias de antemano, y un saludo.


En línea

juligarc10

Desconectado Desconectado

Mensajes: 47


Ver Perfil
Re: varios try catch en un mismo código
« Respuesta #1 en: 19 Febrero 2019, 11:49 am »

Hola gente, ya he conseguido hacer que funcione, pero de todas formas, saben si hay algun metodo más eficiente? Gracias.


En línea

Serapis
Colaborador
***
Desconectado Desconectado

Mensajes: 3.351


Ver Perfil
Re: varios try catch en un mismo código
« Respuesta #2 en: 19 Febrero 2019, 14:04 pm »

La forma de optimizarlo es parametrizarlo en una función, que se invoque para cada consulta que se precise....

Código:
string = funcion Solicitar(string msgPeticion, entero minSize, entero maxSize, buleano soloDigitos, ...)
    buleano ok, rep = false
    string Salida = ""

    Hacer
        mostrar(msgPeticion)
        salida =PedirEntrada
        
        Si ((minSize >0) o (maxSize >0))
            Si (minSize >0)
                si (salida.length < minSize)
                    mostrar("error, debe tener al menos" + minSize + " caracteres...")  
                fin si
            fin si
            Si (maxSize >0)
                si (salida.length > maxSize)
                    mostrar("error, debe tener como máximo" + maxSize + " caracteres...")
                fin si
            fin si
        Fin si

        Si (soloDigitos = TRUE)
            rep = false
            por cada caracter  en salida
                Si (caracter <> digito)
                    mostrar("error, solo se permiten dígitos...")  
                    rep = TRUE  
                    salir del bucle for
                fin si
            Siguiente en bucle  
            si (rep = False)
                OK = TRUE  
            fin si
        Sino
            OK = TRUE
        Fin si  
    repetir mientras (ok=False)

    devolver Salida
fin funcion


Llamada de uso de la función...
Código:
string DNI = Solicitar("Ingrese su DNI", 8, 8, TRUE)  //se solicitan 8 caracteres y deben ser todos dígitos.
objeto.setDNI(DNI)

Algo que no haces correctamente es usar bloques 'Try Catch', alegremente... dichos bloques deben usarse para interceptar errores no tratados en el código (por ejemplo intentar acceder a una unidad de solo lectura con intención de escribir, tu no puedes evitar que si pretendes escribir un fichero el usuario te derive a una unidad de solo lectura, o bien si pero con demasiado código, un bloque try catch, resuelve mucho código en una simple intervención)...pero no para errores para los que precisamente estás interceptando...

Máxime considerando que la interacción con el usuario no se puede considerar un error: si le pides x caracteres, y él los escribe, que tú no los aceptes, no implica un 'error' implica que no se ha validado la entrada... En resumen no fuerces un error inexistente, no ganas nada con ello, excepto complicarte las barbas innecesariamente.

Los bloques Try Catch, existen para intentar salir adelante con errores no interceptados (porque quizás fueren tantos y tan diversos que "sería infinito el código para sumergirse en una aventura", así un bloque Try Catch, permite resumir toda esa aventura en un 'si falla algo dame pistas y si fueran ciertos simples y conocidos vemos de solventarlo... y seguir adelante en vez de dar por terminado el programa.
...pero vamos el error más grave que cometes, es inmiscuir al usuario con errores, como si él mismo fuera un programador o como si tuviera que saber determinados detalles que ni le van ni le vienen. Tu solo le nformas de lo que precisas 'dame el DNI', y si contiene caracteres ilegales, le sueltas un 'repite, porque hay caracteres extraños y solo debe tener dígitos'.... como es una simple comprobación que tienes que hacer si o sí, conoces el problema y entonces el bloque try catch, resulta usado en abuso.

El programador todavía debe generar errores, en situaciones donde él mismo u otro que utilice el componente que has realizado, genere rsultados erróneos. Por ejemplo, si creas un objeto que solicite una entrada al usuario y la deuelve sin procesar, y dicho objeto tenía un parámetro de 'solo dígitos', está bien que generes un error para que el objeto que lo reciba sepa que debe tratarlo, así el objeto que lo recibe puede mostrar el mensaje oportuno al usuario y volver a solicitarlo, o si le es posible ignorarlo, seguir adelante...
...por ejemplo, supongamos que se pide el dni, y el usuario escribió: 88555222H se soluciona el problema si se retira la 'H', o incluso se le podía preguntar: confirme si es éste el numero correcto: 88555222 sin la 'H', que es el carácter no válido, otro ejemplo: 88sd@45, como hay que eliminar más de 1 carácter y sigue sin tener el largo esperado de dígitos, procede mejor solicitar que se ingrese de nuevo?).


Forzando el mismo pseudocódigo previo, como 2 objetos distintos, donde el primero es un servicio que utiliza el segundo... que ahí si tendría sentido un try catch.

Código:
string = funcion Solicitar(string msgPeticion, entero minSize, entero maxSize, buleano soloDigitos, ...)
    string Salida = ""

    mostrar(msgPeticion)
    salida =PedirEntrada
    
    Si ((minSize >0) o (maxSize >0))
        Si (minSize >0)
            si (salida.length < minSize)
                disparar error SizeIlegal
                //devolver error  el código sale desde la línea previa, es equivalente a devolver el error.
            fin si
        fin si
        Si (maxSize >0)
            si (salida.length > maxSize)
                disparar error SizeIlegal
                //devolver error  el código sale desde la línea previa, es equivalente a devolver el error.
            fin si
        fin si
    Fin si

    Si (soloDigitos = TRUE)
        por cada caracter  en salida
            Si (caracter <> digito)
                disparar error CaracterIlegal
                //devolver error el código sale desde la línea previa, es equivalente a devolver el error.
            fin si
        siguient en bucle  
    Fin si  

    devolver Salida
fin funcion

Lo previo sería el código de una función dentro de un objeto, se ve que es casi identico al previo, excepto que no está en un bucle, e intercepta dos tipos de errores, que comunicará al objeto cliente.

Llamada de uso de la función...
Código:
Do
    Try
        string DNI = servicio.Solicitar("Ingrese su DNI", 8, 8, TRUE)  //se solicitan 8 caracteres y deben ser todos dígitos.
        objeto.setDNI(DNI)
    Catch (excepcion)
        Si (excepcion= SizeIlegal)
            MostrarMensaje("debe tener 8 caracteres, ni más ni menos")
        OSi (excepcion= CaracterIlegal)
            MostrarMensaje("Solo debe contener dígitos")
        Fin si
    End try
Loop while excepcion


Como puedes ver ambos códigos son muy similares... pero hay claras diferencias... en el primero, tú controlas todos, porque está todo en el mismo objeto, conoces los posibleserrores, porque sabes lo que eseras, luego no proceder generar errores.
En cambio en este segundo ejemplo (es básicamente lo msmo que el previo), la función 'Solictar' yace en otro objeto distinto de tú código, al que tu invocas... aquel método, simplemente genera  un mensaje bajo ciertas condiciones y está capacitado para arrojar un error si no se cumplen, pero allí a diferencia del ejemplo previo, no tiene un bucle... quien sabe si el programador quisiera darle al usuario la opción de abortar?... en cambio tú ahora en tu código si debes tratar las excepciones, pero nota que las excepciones se dan de cara al código, con el que el programador debe lifdiar, no al usuario...

En fin, la línea es delgadita, sibilina, pero es importante percibirla con clardad. Repasa cuantas veces sea ambos códigos con los comentarios hasta que percibas claramente la diferencia entre ellas y el porqué del asunto.


P.D.: Nota por último, como lo importante de dicha función (sobre otro objeto) es que luego permite simplificar enormemente la operatoria de verificación... simplemente haces una llamada y verificas las posibles excepciones... (si hubiere muchas más, sacas un mensaje genérico sobre como se espera que sea lo correcto), pero no precisas hacer para cada ppeticion, DNI, nombre, Calle, Número de calle o piso, etc... toda esa operatoria, que sería mucho código. Además de más breve, resulta mucho más legible, porque la propia función 'Solicitar' queda encapsulada en otro objeto...
Nota también que para atrapar los diferentes aspectos en que pudieran incurrir todos esos mensajes deben ser parametrizados y tratados en la funcón, yo solo he puesto de ejemplo el tamaño mínimo y máximo de caracteres y en que se permitan solo dígitos... pero habrá más casos.
« Última modificación: 19 Febrero 2019, 14:45 pm por NEBIRE » En línea

juligarc10

Desconectado Desconectado

Mensajes: 47


Ver Perfil
Re: varios try catch en un mismo código
« Respuesta #3 en: 19 Febrero 2019, 15:25 pm »

La forma de optimizarlo es parametrizarlo en una función, que se invoque para cada consulta que se precise....

Código:
string = funcion Solicitar(string msgPeticion, entero minSize, entero maxSize, buleano soloDigitos, ...)
    buleano ok, rep = false
    string Salida = ""

    Hacer
        mostrar(msgPeticion)
        salida =PedirEntrada
        
        Si ((minSize >0) o (maxSize >0))
            Si (minSize >0)
                si (salida.length < minSize)
                    mostrar("error, debe tener al menos" + minSize + " caracteres...")  
                fin si
            fin si
            Si (maxSize >0)
                si (salida.length > maxSize)
                    mostrar("error, debe tener como máximo" + maxSize + " caracteres...")
                fin si
            fin si
        Fin si

        Si (soloDigitos = TRUE)
            rep = false
            por cada caracter  en salida
                Si (caracter <> digito)
                    mostrar("error, solo se permiten dígitos...")  
                    rep = TRUE  
                    salir del bucle for
                fin si
            Siguiente en bucle  
            si (rep = False)
                OK = TRUE  
            fin si
        Sino
            OK = TRUE
        Fin si  
    repetir mientras (ok=False)

    devolver Salida
fin funcion


Llamada de uso de la función...
Código:
string DNI = Solicitar("Ingrese su DNI", 8, 8, TRUE)  //se solicitan 8 caracteres y deben ser todos dígitos.
objeto.setDNI(DNI)

Algo que no haces correctamente es usar bloques 'Try Catch', alegremente... dichos bloques deben usarse para interceptar errores no tratados en el código (por ejemplo intentar acceder a una unidad de solo lectura con intención de escribir, tu no puedes evitar que si pretendes escribir un fichero el usuario te derive a una unidad de solo lectura, o bien si pero con demasiado código, un bloque try catch, resuelve mucho código en una simple intervención)...pero no para errores para los que precisamente estás interceptando...

Máxime considerando que la interacción con el usuario no se puede considerar un error: si le pides x caracteres, y él los escribe, que tú no los aceptes, no implica un 'error' implica que no se ha validado la entrada... En resumen no fuerces un error inexistente, no ganas nada con ello, excepto complicarte las barbas innecesariamente.

Los bloques Try Catch, existen para intentar salir adelante con errores no interceptados (porque quizás fueren tantos y tan diversos que "sería infinito el código para sumergirse en una aventura", así un bloque Try Catch, permite resumir toda esa aventura en un 'si falla algo dame pistas y si fueran ciertos simples y conocidos vemos de solventarlo... y seguir adelante en vez de dar por terminado el programa.
...pero vamos el error más grave que cometes, es inmiscuir al usuario con errores, como si él mismo fuera un programador o como si tuviera que saber determinados detalles que ni le van ni le vienen. Tu solo le nformas de lo que precisas 'dame el DNI', y si contiene caracteres ilegales, le sueltas un 'repite, porque hay caracteres extraños y solo debe tener dígitos'.... como es una simple comprobación que tienes que hacer si o sí, conoces el problema y entonces el bloque try catch, resulta usado en abuso.

El programador todavía debe generar errores, en situaciones donde él mismo u otro que utilice el componente que has realizado, genere rsultados erróneos. Por ejemplo, si creas un objeto que solicite una entrada al usuario y la deuelve sin procesar, y dicho objeto tenía un parámetro de 'solo dígitos', está bien que generes un error para que el objeto que lo reciba sepa que debe tratarlo, así el objeto que lo recibe puede mostrar el mensaje oportuno al usuario y volver a solicitarlo, o si le es posible ignorarlo, seguir adelante...
...por ejemplo, supongamos que se pide el dni, y el usuario escribió: 88555222H se soluciona el problema si se retira la 'H', o incluso se le podía preguntar: confirme si es éste el numero correcto: 88555222 sin la 'H', que es el carácter no válido, otro ejemplo: 88sd@45, como hay que eliminar más de 1 carácter y sigue sin tener el largo esperado de dígitos, procede mejor solicitar que se ingrese de nuevo?).


Forzando el mismo pseudocódigo previo, como 2 objetos distintos, donde el primero es un servicio que utiliza el segundo... que ahí si tendría sentido un try catch.

Código:
string = funcion Solicitar(string msgPeticion, entero minSize, entero maxSize, buleano soloDigitos, ...)
    string Salida = ""

    mostrar(msgPeticion)
    salida =PedirEntrada
    
    Si ((minSize >0) o (maxSize >0))
        Si (minSize >0)
            si (salida.length < minSize)
                disparar error SizeIlegal
                //devolver error  el código sale desde la línea previa, es equivalente a devolver el error.
            fin si
        fin si
        Si (maxSize >0)
            si (salida.length > maxSize)
                disparar error SizeIlegal
                //devolver error  el código sale desde la línea previa, es equivalente a devolver el error.
            fin si
        fin si
    Fin si

    Si (soloDigitos = TRUE)
        por cada caracter  en salida
            Si (caracter <> digito)
                disparar error CaracterIlegal
                //devolver error el código sale desde la línea previa, es equivalente a devolver el error.
            fin si
        siguient en bucle  
    Fin si  

    devolver Salida
fin funcion

Lo previo sería el código de una función dentro de un objeto, se ve que es casi identico al previo, excepto que no está en un bucle, e intercepta dos tipos de errores, que comunicará al objeto cliente.

Llamada de uso de la función...
Código:
Do
    Try
        string DNI = servicio.Solicitar("Ingrese su DNI", 8, 8, TRUE)  //se solicitan 8 caracteres y deben ser todos dígitos.
        objeto.setDNI(DNI)
    Catch (excepcion)
        Si (excepcion= SizeIlegal)
            MostrarMensaje("debe tener 8 caracteres, ni más ni menos")
        OSi (excepcion= CaracterIlegal)
            MostrarMensaje("Solo debe contener dígitos")
        Fin si
    End try
Loop while excepcion


Como puedes ver ambos códigos son muy similares... pero hay claras diferencias... en el primero, tú controlas todos, porque está todo en el mismo objeto, conoces los posibleserrores, porque sabes lo que eseras, luego no proceder generar errores.
En cambio en este segundo ejemplo (es básicamente lo msmo que el previo), la función 'Solictar' yace en otro objeto distinto de tú código, al que tu invocas... aquel método, simplemente genera  un mensaje bajo ciertas condiciones y está capacitado para arrojar un error si no se cumplen, pero allí a diferencia del ejemplo previo, no tiene un bucle... quien sabe si el programador quisiera darle al usuario la opción de abortar?... en cambio tú ahora en tu código si debes tratar las excepciones, pero nota que las excepciones se dan de cara al código, con el que el programador debe lifdiar, no al usuario...

En fin, la línea es delgadita, sibilina, pero es importante percibirla con clardad. Repasa cuantas veces sea ambos códigos con los comentarios hasta que percibas claramente la diferencia entre ellas y el porqué del asunto.


P.D.: Nota por último, como lo importante de dicha función (sobre otro objeto) es que luego permite simplificar enormemente la operatoria de verificación... simplemente haces una llamada y verificas las posibles excepciones... (si hubiere muchas más, sacas un mensaje genérico sobre como se espera que sea lo correcto), pero no precisas hacer para cada ppeticion, DNI, nombre, Calle, Número de calle o piso, etc... toda esa operatoria, que sería mucho código. Además de más breve, resulta mucho más legible, porque la propia función 'Solicitar' queda encapsulada en otro objeto...
Nota también que para atrapar los diferentes aspectos en que pudieran incurrir todos esos mensajes deben ser parametrizados y tratados en la funcón, yo solo he puesto de ejemplo el tamaño mínimo y máximo de caracteres y en que se permitan solo dígitos... pero habrá más casos.

Muchas gracias amigo. Me fue de gran ayuda tu comentario ;-)

Un saludo.
En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines