Usar try / catch para evitar que la aplicación se bloquee

79

He estado trabajando en una aplicación de Android que se usa con try/catchfrecuencia para evitar que se bloquee incluso en lugares donde no es necesario. Por ejemplo,

Una vista xml layoutcon id = toolbarse hace referencia como:

// see new example below, this one is just confusing
// it seems like I am asking about empty try/catch
try {
    View view = findViewById(R.id.toolbar);
}
catch(Exception e) {
}

Este enfoque se utiliza en toda la aplicación. El seguimiento de la pila no se imprime y es muy difícil encontrar qué salió mal. La aplicación se cierra repentinamente sin imprimir ningún rastro de pila.

Le pedí a mi superior que me lo explicara y me dijo:

Esto es para prevenir fallas en la producción.

Estoy totalmente en desacuerdo con eso . Para mí, esta no es la forma de evitar que las aplicaciones se bloqueen. Muestra que el desarrollador no sabe lo que está haciendo y tiene dudas.

¿Es este el enfoque que se utiliza en la industria para evitar fallas en las aplicaciones empresariales?

Si try/catches realmente, realmente nuestra necesidad, ¿es posible adjuntar un controlador de excepciones con el hilo de la interfaz de usuario u otros hilos y capturar todo allí? Ese será un mejor enfoque si es posible.

Sí, vacío try/catches malo e incluso si imprimimos el seguimiento de la pila o la excepción de registro en el servidor, encapsular bloques de código try/catchaleatoriamente en toda la aplicación no tiene sentido para mí, por ejemplo, cuando cada función está incluida en un try/catch.

ACTUALIZAR

Como esta pregunta ha recibido mucha atención y algunas personas la han malinterpretado (tal vez porque no la he redactado claramente), la voy a reformular.

Esto es lo que hacen los desarrolladores aquí

  • Una función está escrita y probada , puede ser una función pequeña que simplemente inicializa vistas o una función compleja, después de probarla se envuelve alrededor del try/catchbloque. Incluso para una función que nunca arrojará ninguna excepción.

  • Esta práctica se utiliza en toda la aplicación. En ocasiones, se imprime el seguimiento de la pila y, en ocasiones, solo aparece un debug logmensaje de error aleatorio. Este mensaje de error difiere de un desarrollador a otro.

  • Con este enfoque, la aplicación no se bloquea, pero el comportamiento de la aplicación se vuelve indeterminado. Incluso a veces es difícil seguir lo que salió mal.

  • La verdadera pregunta que he estado haciendo fue; ¿Es la práctica que se sigue en la industria para prevenir fallas en las aplicaciones empresariales? y no estoy preguntando por try / catch vacío . ¿Es como que a los usuarios les encantan las aplicaciones que no fallan que las aplicaciones que se comportan inesperadamente? Porque realmente se reduce a bloquearlo o presentar al usuario una pantalla en blanco o el comportamiento que el usuario desconoce.

  • Estoy publicando algunos fragmentos del código real aquí.

      private void makeRequestForForgetPassword() {
        try {
            HashMap<String, Object> params = new HashMap<>();
    
            String email= CurrentUserData.msisdn;
            params.put("email", "blabla");
            params.put("new_password", password);
    
            NetworkProcess networkProcessForgetStep = new NetworkProcess(
                serviceCallListenerForgotPasswordStep, ForgotPassword.this);
            networkProcessForgetStep.serviceProcessing(params, 
                Constants.API_FORGOT_PASSWORD);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
     private void languagePopUpDialog(View view) {
        try {
            PopupWindow popupwindow_obj = popupDisplay();
            popupwindow_obj.showAsDropDown(view, -50, 0);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    void reloadActivity() {
        try {
            onCreateProcess();
        } catch (Exception e) {
        }
    }
    

No es un duplicado de las mejores prácticas de manejo de excepciones de Android , OP está tratando de detectar la excepción para un propósito diferente al de esta pregunta.

mallaudin
fuente
11
No respondo a su pregunta, pero nunca trague las excepciones a medias catch(Exception e){}- este comentario tenía sentido antes de la edición de la pregunta
Scary Wombat
29
Ah, el infameON ERROR RESUME NEXT
Deduplicator
Los comentarios no son para una discusión extensa; esta conversación se ha movido al chat .
Bhargav Rao
1
Esta pregunta me hizo pensar, porque también uso el try {} catch (Exception e) {} muchas veces cuando se me acaba el tiempo
Raut Darpan

Respuestas:

81

Por supuesto, siempre hay excepciones a las reglas, pero si necesita una regla general, entonces está en lo correcto; Los bloques de captura vacíos son "absolutamente" una mala práctica.

Echemos un vistazo más de cerca, primero comenzando con su ejemplo específico:

try {
  View view = findViewById(R.id.toolbar);
}
catch(Exception e) { }

Entonces, se crea una referencia a algo; y cuando eso falla ... no importa; ¡porque esa referencia no se usa en primer lugar! El código anterior es un ruido de línea absolutamente inútil . ¿O la persona que escribió ese código inicialmente asume que una segunda llamada similar mágicamente ya no arrojaría una excepción?

Tal vez esto estaba destinado a verse así:

try {
  View view = findViewById(R.id.toolbar);
  ... and now do something with that view variable ...
}
catch(Exception e) { }

Pero de nuevo, ¡¿en qué ayuda esto ?! Existen excepciones para comunicar respectivamente propagar situaciones de error dentro de su código. Ignorar los errores rara vez es una buena idea. En realidad, una excepción puede tratarse de la siguiente manera:

  • Le das retroalimentación al usuario; (como: "el valor que ingresó no es una cadena, inténtelo de nuevo"); o participar en un manejo de errores más complejo
  • Quizás el problema se espera de alguna manera y se puede mitigar (por ejemplo, dando una respuesta "predeterminada" cuando falla alguna "búsqueda remota")
  • ...

En pocas palabras: lo mínimo que puede hacer con una excepción es registrarla / rastrearla; para que cuando vengas más tarde depurando algún problema entiendas "OK, en este momento ocurrió esa excepción".

Y como han señalado otros: también evita la captura de excepción en general (bueno, dependiendo de la capa: puede haber buenas razones para tener alguna captura de excepción , e incluso algunos tipos de errores en el nivel más alto, para asegurarse de que nada se pierde; nunca ).

Finalmente, citemos a Ward Cunningham:

Sabes que estás trabajando con código limpio cuando cada rutina que lees resulta ser más o menos lo que esperabas. Puede llamarlo código hermoso cuando el código también hace que parezca que el lenguaje fue creado para el problema.

Deje que eso se hunda y medite sobre ello. El código limpio no te sorprende. El ejemplo que nos muestra sorprende a todos los que lo miran.

Actualización , con respecto a la actualización sobre la que pregunta el OP

try {
  do something
}
catch(Exception e) { 
  print stacktrace
}

Misma respuesta: hacer eso "por todas partes" también es una mala práctica. Porque este código también sorprende al lector.

Lo anterior:

  • Imprime información de error en alguna parte. No se garantiza en absoluto que este "lugar" se asemeje a un destino razonable . De lo contrario. Ejemplo: dentro de la aplicación con la que estoy trabajando, tales llamadas aparecerían mágicamente en nuestros búferes de seguimiento. Dependiendo del contexto, nuestra aplicación puede bombear toneladas y toneladas de datos a esos búferes a veces; haciendo que esos búfer poden cada pocos segundos. Entonces, "solo errores de impresión" a menudo se traduce como: "simplemente perder toda esa información de error".
  • Entonces: no intente / atrape porque puede . Lo hace porque comprende lo que hace su código; y ya sabes: será mejor que intente / atrape aquí para hacer lo correcto (vea las primeras partes de mi respuesta nuevamente).

Entonces, usando try / catch como "patrón" como se muestra; es como se dijo: todavía no es una buena idea. Y sí, previene caídas; pero conduce a todo tipo de comportamiento "indefinido". Ya sabe, cuando detecta una excepción en lugar de tratarla correctamente ; abres una lata de gusanos; porque puede encontrarse con innumerables errores de seguimiento que luego no comprenderá. Porque consumió el evento "causa raíz" anteriormente; impreso en alguna parte; y ese lugar ahora se ha ido.

GhostCat
fuente
1
¿Qué pasa si imprimo el seguimiento de la pila? Todavía no creo que necesite intentarlo / atraparlo aquí.
mallaudin
3
Tengo que admitir que no entiendo tu edición. No es una idea real de lo que estás haciendo allí; o adónde estás llegando con esto.
GhostCat
@mallaudin en un caso general, cualquier cosa después de la línea que bloquee el programa no se ejecutará (obvio), por lo que imprimir es una tontería. En este caso específico, es decir, intente + excepto, al menos se mostraría algo y la excepción no se silenciaría.
Peter Badida
2
@GhostCat El OP dice en un comentario en otra respuesta que los bloques de excepción ya contienen llamadas de registro. La pregunta tergiversa lo que realmente está sucediendo, por lo que no creo que acusar al desarrollador senior de ser incompetente sea útil aquí. Creo que están sucediendo más cosas de las que nos ofrece el OP.
jpmc26
1
@GhostCat no se trata de repo, me acabo de dar cuenta de que mi ejemplo era malo. Todo el mundo pensó que estaba preguntando sobre try / catch vacío
mallaudin
15

De la documentación de Android :

Vamos a titularlo como -

No detecte la excepción genérica

También puede ser tentador ser perezoso al detectar excepciones y hacer algo como esto:

try {
    someComplicatedIOFunction();        // may throw IOException
    someComplicatedParsingFunction();   // may throw ParsingException
    someComplicatedSecurityFunction();  // may throw SecurityException
    // phew, made it all the way
} catch (Exception e) {                 // I'll just catch all exceptions
    handleError();                      // with one generic handler!
}

En casi todos los casos, es inapropiado capturar genérico Exceptiono Throwable (preferiblemente no Throwable porque incluye excepciones de error). Es muy peligroso porque significa que las excepciones que nunca esperó (incluidos los me RuntimeExceptionsgusta ClassCastException) quedan atrapadas en el manejo de errores a nivel de aplicación.

Oculta las propiedades de manejo de fallas de su código, lo que significa que si alguien agrega un nuevo tipo Exceptionen el código que está llamando, el compilador no lo ayudará a darse cuenta de que necesita manejar el error de manera diferente .

Alternativas a la captura de excepciones genéricas:

  • Capture cada excepción por separado como bloques de captura separados después de un solo intento. Esto puede resultar incómodo, pero es preferible que capturar todas las excepciones.
    Editar por autor: esta es mi elección. Tenga cuidado de repetir demasiado código en los bloques de captura. Si está utilizando Java 7 o superior, use captura múltiple para evitar repetir el mismo bloque de captura.
  • Refactorice su código para tener un manejo de errores más detallado , con múltiples bloques de prueba. Divida el IO del análisis, maneje los errores por separado en cada caso.
  • Vuelva a lanzar la excepción . Muchas veces no es necesario detectar la excepción en este nivel de todos modos, simplemente deje que el método la arroje.

En la mayoría de los casos, no debería manejar diferentes tipos de excepción de la misma manera.

Formato / párrafo ligeramente modificado de la fuente para esta respuesta.

PD: ¡No tengas miedo de las excepciones! ¡¡¡Ellos son amigos!!!

Paresh P.
fuente
1
si detecta cada excepción individualmente, asegúrese de evitar continuar la ejecución en un estado incierto (evite cosas como Object a; try { a = thing(); } catch (Exception e) {...} try { a.action(); } catch (Exception e) {...}))
njzk2
Para ser justos, la captura de genéricos Exceptionpodría ser útil como parte de un sistema de "registro antes de fallar", aunque debería volver a lanzar en ese caso.
Justin Time - Reincorpora a Monica
9

Pondría esto como un comentario a otra respuesta, pero todavía no tengo la reputación de eso.

Tiene razón al decir que es una mala práctica; de hecho, lo que publicó muestra diferentes tipos de malas prácticas con respecto a las excepciones.

  1. Falta de manejo de errores
  2. Captura genérica
  3. Sin excepciones intencionales
  4. Prueba / captura de manta

Intentaré explicar todos esos a través de este ejemplo.

try {
   User user = loadUserFromWeb();     
   if(user.getCountry().equals("us")) {  
       enableExtraFields();
   }
   fillFields(user);   
} catch (Exception e) { 
}

Esto puede fallar de varias formas que deben manejarse de manera diferente.

  1. Los campos no se completarán, por lo que al usuario se le presenta una pantalla vacía y luego ... Nada: falta de manejo de errores.
  2. No hay distinción entre diferentes tipos de errores, por ejemplo, problemas de Internet o problemas con el servidor en sí (interrupción, solicitud rota, transmisión dañada, ...) - Captura genérica.
  3. No puede usar excepciones para sus propios fines porque el sistema actual interfiere con eso. - Sin excepciones intencionales
  4. Los errores no esenciales e inesperados (por ejemplo, null.equals (...)) pueden hacer que el código esencial no se ejecute. - Prueba / captura de manta

Soluciones

(1) Primero que nada, fallar en silencio no es algo bueno. Si hay una falla, la aplicación no funcionará. En su lugar, debería haber un intento de resolver el problema o mostrar una advertencia, por ejemplo "No se pudieron cargar los datos del usuario, ¿quizás no está conectado a Internet?". Si la aplicación no está haciendo lo que se supone que debe hacer, es mucho más frustrante para el usuario que si simplemente se cierra.

(4) Si el usuario está incompleto, por ejemplo, el país no se conoce y devuelve nulo. El método equals creará una NullPointerException. Si ese NPE simplemente se lanza y se captura como arriba, no se llamará al método fillFields (usuario), aunque aún podría ejecutarse sin problemas. Puede evitar esto incluyendo comprobaciones nulas, cambiando el orden de ejecución o ajustando el alcance de prueba / captura. (O podría guardar la codificación como esta: "nosotros" .equals (user.getCountry ()), pero tenía que dar un ejemplo). Por supuesto, cualquier otra excepción también evitará que se ejecute fillFields (), pero si no hay un usuario, probablemente no desee que se ejecute de todos modos.

(1, 2, 3) La carga desde la web a menudo arroja una variedad de excepciones, desde IOException hasta la excepción HttpMessageNotReadable e incluso simplemente regresar. Podría ser que el usuario no esté conectado a Internet, podría ser que hubo un cambio en un servidor backend o que no funciona, pero no lo sabe porque detecta (Excepción); en su lugar, debe detectar excepciones específicas. Incluso puedes atrapar a varios de ellos así.

try{
   User user = loadUserFromWeb(); //throws NoInternetException, ServerNotAvailableException or returns null if user does not exist
   if(user == null) { 
       throw new UserDoesNotExistException(); //there might be better options to solve this, but it highlights how exceptions can be used.
   }
   fillFields(user);
   if("us".equals(user.getCountry()) {
       enableExtraFields();
   }
} catch(NoInternetException e){
    displayWarning("Your internet conneciton is down :(");
} catch(ServerNotAvailableException e){
    displayWarning("Seems like our server is having trouble, try again later.");
} catch(UserDoesNotExistException e){
    startCreateUserActivity();
}

Espero que esto lo explique.

Al menos como una solución rápida, lo que podría hacer es enviar un evento a su backend con la excepción. Por ejemplo, a través de firebase o crashlytics. De esa manera, al menos puede ver cosas como (oye, la actividad principal no se carga para el 80% de nuestros usuarios debido a un problema como (4).

Syzygy
fuente
8

Definitivamente es una mala práctica de programación.

Desde el escenario actual, si hay cientos de try catcheste tipo, ni siquiera sabrá dónde ocurre la excepción sin depurar la aplicación, lo cual es una pesadilla si su aplicación está en un entorno de producción.

Pero puede incluir un registrador para saber cuándo se lanza una excepción (y por qué). No cambiará su flujo de trabajo normal.

...
try {
    View view = findViewById(R.id.toolbar);
}catch(Exception e){
    logger.log(Level.SEVERE, "an exception was thrown", e);
}
...
Raman Sahasi
fuente
7

Esta es una mala práctica. Otras respuestas han dicho eso, pero creo que es importante dar un paso atrás y comprender por qué tenemos excepciones en primer lugar.

Cada función tiene una condición posterior : un conjunto de cosas que deben ser verdaderas después de que se ejecute esa función. Por ejemplo, una función que lee de un archivo tiene la condición posterior de que los datos del archivo se leerán del disco y se devolverán. Entonces, se lanza una excepción cuando una función no ha podido satisfacer una de sus condiciones posteriores.

Al ignorar una excepción de una función (o incluso ignorarla de manera efectiva simplemente registrando la excepción), está diciendo que está de acuerdo con que esa función no esté haciendo todo el trabajo que acordó hacer. Esto parece poco probable: si una función no se ejecuta correctamente, no hay garantía de que lo que sigue se ejecute en absoluto. Y si el resto de su código funciona bien, ya sea que una función en particular se complete o no, entonces uno se pregunta por qué tiene esa función en primer lugar.

[Ahora bien, hay ciertos casos en los que catchestá bien que esté vacío . Por ejemplo, el registro es algo que podría justificar envolver en una captura vacía. Su aplicación probablemente funcionará bien incluso si no se puede escribir parte del registro. Pero esos son casos especiales que tienes que esforzarte mucho para encontrarlos en una aplicación normal.]

Entonces, el punto es que esta es una mala práctica porque en realidad no mantiene la aplicación en funcionamiento (la supuesta justificación de este estilo). Quizás técnicamente el sistema operativo no lo ha matado. Pero es poco probable que la aplicación siga funcionando correctamente después de simplemente ignorar una excepción. Y en el peor de los casos, podría estar causando daño (por ejemplo, corrompiendo archivos de usuario, etc.).

JoshG79
fuente
3

Esto es malo por varias razones:

  1. ¿Qué estás haciendo que findViewByIdarroja una excepción? Arregle eso (y dígame, porque nunca he visto esto) en lugar de atraparlo.
  2. No detecte Exceptioncuándo podría detectar un tipo específico de excepción.
  3. Existe la creencia de que las buenas aplicaciones no fallan. Eso no es cierto. Una buena aplicación se bloquea si debe hacerlo.

Si una aplicación entra en mal estado, es mucho mejor que se bloquee que que funcione en su estado inutilizable. Cuando uno ve una NPE, uno no debería simplemente poner un cheque nulo y alejarse. El mejor enfoque es averiguar por qué algo es nulo y evitar que sea nulo o (si el nulo termina siendo un estado válido y esperado) comprobar si es nulo. Pero debes entender por qué ocurre el problema en primer lugar.

AJ
fuente
2

He estado desarrollando aplicaciones de Android durante los últimos 4-5 años y nunca usé un try catch para la inicialización de la vista.

Si es una barra de herramientas, hazlo así

Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);

por ejemplo: - Para obtener un TextView de una vista (fragmento / diálogo / cualquier vista personalizada)

TextView textview = (TextView) view.findViewById(R.id.viewId);

TextView textview = (TextView) view.findViewById (R.id.viewId);

en lugar de esto

View view = findViewById(R.id.toolbar);

Un objeto de vista tiene un alcance mínimo en comparación con su tipo de vista real.

Nota: - Puede que se bloquee porque se cargó la vista. Pero agregar try catch es una mala práctica.

shijin
fuente
En muchos casos, no es necesario emitir la vista. Hay algunos métodos que tiene Viewque pueden ser útiles (como setVisibility()), sin que especifique exactamente qué clase se usa. (por ejemplo, en el caso de un diseño, que es susceptible de ser cambiado de vez en cuando)
njzk2
1

Sí, try / catch se usa para evitar que la aplicación se bloquee, pero ciertamente no es necesario try / catch para obtener una vista de XML como se muestra en su pregunta.

try / catch se usa generalmente al realizar cualquier solicitud http, al analizar cualquier String a URL, crear conexiones URL, etc. y también asegurarse de imprimir el seguimiento de la pila. No imprimirlo no tiene mucho sentido rodearlo con try / catch.

Chandrani Chatterjee
fuente
1

Como se dijo antes, las excepciones generales no deben detectarse, o al menos solo en algunos lugares centrales (generalmente ubicadas en el código de infraestructura / marco, no en el código de la aplicación). Si se detectan excepciones generales y se registran, la aplicación debe cerrarse posteriormente o, como mínimo, se debe informar al usuario de que la aplicación está potencialmente en un estado inestable y que podrían producirse daños en los datos (si el usuario elige continuar con la ejecución). Porque esto es lo que podría suceder si detecta todo tipo de excepciones (sin memoria para nombrar una) y deja la aplicación en un estado indefinido.

En mi humilde opinión, es peor aceptar las excepciones y arriesgar la integridad de los datos, la pérdida de datos o simplemente dejar la aplicación en un estado indefinido que dejar que la aplicación se bloquee y el usuario sepa que algo salió mal y puede volver a intentarlo. Esto también conducirá a mejores problemas informados (más en la raíz del problema), probablemente menos síntomas diferentes que si sus usuarios comienzan a informar todo tipo de problemas que se originan en un estado de aplicación indefinido.

Después de que se haya implementado un manejo / registro / reporte central de excepciones y un apagado controlado, comience a reescribir el manejo de excepciones para detectar excepciones locales lo más específicas posible. Intenta que el bloque try {} sea lo más breve posible.

DavWEB
fuente
1

Permítanme agregar mi punto de vista, como un hombre que trabaja en la industria del desarrollo móvil corporativo durante más de una década. Primero, algunos consejos generales sobre excepciones, la mayoría de ellos incluidos en las respuestas anteriores:

  • Las excepciones deben usarse para situaciones excepcionales, inesperadas o incontroladas, no de forma regular a lo largo del código.
  • Un programador debe conocer las partes del código susceptibles de lanzar excepciones e intentar capturarlas, dejando el resto del código lo más limpio posible.
  • Las excepciones no deben quedar calladas, como regla general.

Ahora, cuando no está desarrollando una aplicación para usted, sino para una empresa o corporación, es común enfrentar requisitos adicionales sobre este tema:

  • "Los fallos de aplicaciones muestran una mala imagen de la empresa, por lo que no son aceptables". Luego, se debe realizar un desarrollo cuidadoso, y la detección de excepciones incluso improbables puede ser una opción. Si es así, esto debe hacerse de forma selectiva y mantenerse dentro de límites razonables. Y tenga en cuenta que el desarrollo no se trata solo de líneas de código, por ejemplo, un proceso de prueba intensivo es fundamental en estos casos. Sin embargo, un comportamiento inesperado en una aplicación corporativa es peor que fallar. Por lo tanto, siempre que detecte una excepción en su aplicación, debe saber qué hacer, qué mostrar y cómo se comportará la aplicación a continuación. Si no puede controlar eso, mejor deje que la aplicación se bloquee.
  • "Los registros y los seguimientos de pila pueden volcar información confidencial en la consola. Eso podría ser utilizado por un atacante, por lo que por razones de seguridad no se puede utilizar en un entorno de producción". Este requisito entra en conflicto con la regla general de que un desarrollador no escriba excepciones silenciosas, por lo que debe encontrar una manera de hacerlo. Por ejemplo, su aplicación podría controlar el entorno, por lo que utiliza registros y seguimientos de pila en entornos que no son de producción, mientras utiliza herramientas basadas en la nube como bugsense, crashlitics o similares para entornos de producción.

Entonces, la respuesta corta es que el código que encontró no es un ejemplo de buenas prácticas, ya que es difícil y costoso de mantener sin mejorar la calidad de la aplicación.

Miguel
fuente
1

Otra perspectiva, como alguien que escribe software empresarial a diario, si una aplicación tiene un error irrecuperable, quiero que se bloquee. Es deseable estrellarse. Si falla, se registra. Si falla más de unas pocas veces en un corto período de tiempo, recibo un correo electrónico que dice que la aplicación falla y puedo verificar que nuestra aplicación y todos los servicios web que consumimos aún funcionan.

Entonces la pregunta:

Es

try{
  someMethod();
}catch(Exception e){}

¿buena práctica? ¡No! Aquí hay algunos puntos:

  1. Lo MÁS importante: esta es una mala experiencia para el cliente. ¿Cómo se supone que voy a saber cuando está sucediendo algo malo? Mis clientes están intentando usar mi aplicación y nada funciona. No pueden consultar su cuenta bancaria, pagar sus facturas, haga lo que haga mi aplicación. Mi aplicación es completamente inútil, pero bueno, ¡al menos no se bloqueó! (Parte de mí cree que este desarrollador "sénior" obtiene puntos brownie por números bajos de fallas, por lo que están jugando con el sistema).

  2. Cuando estoy desarrollando y escribo un código incorrecto, si solo estoy capturando y tragando todas las excepciones en la capa superior, no tengo registro. No tengo nada en mi consola y mi aplicación falla silenciosamente. Por lo que puedo decir, todo parece funcionar bien. Entonces confirmo el código ... Resulta que mi objeto DAO fue nulo todo el tiempo, y los pagos del cliente nunca se actualizaron realmente en la base de datos. ¡Ups! Pero mi aplicación no falló, eso es una ventaja.

  3. Jugando al abogado del diablo, digamos que estaba de acuerdo con atrapar y tragar todas las excepciones. Es extremadamente fácil escribir un controlador de excepciones personalizado en Android. Si realmente solo tiene que detectar todas las excepciones, puede hacerlo en un solo lugar y no salpicar try/catchtodo el código.

Algunos de los desarrolladores con los que he trabajado en el pasado pensaban que las fallas eran malas.

Tengo que asegurarles que queremos que nuestra aplicación falle. No, una aplicación inestable no está bien, pero un bloqueo significa que hicimos algo mal y tenemos que arreglarlo. Cuanto más rápido se bloquee, cuanto antes lo encontremos, más fácil será repararlo. La única otra opción en la que puedo pensar es permitir que el usuario continúe en una sesión rota, lo que yo equiparo con cabrear mi base de usuarios.

Christopher Schneider
fuente
0

Es una mala práctica usarlo catch(Exception e){}porque esencialmente está ignorando el error. Lo que probablemente quieras hacer es algo más como:

try {
    //run code that could crash here
} catch (Exception e) {
    System.out.println(e.getMessage());
}
Chris
fuente
0

Prácticamente usamos tu misma lógica. Úselo try-catchpara evitar que las aplicaciones de producción se bloqueen.

Las excepciones NUNCA deben ignorarse. Es una mala práctica de codificación. Los chicos que mantienen el código tendrán realmente dificultades para localizar la parte del código que generó la excepción si no están registrados.

Usamos Crashlyticspara registrar las excepciones. El código no se bloqueará (pero se interrumpirán algunas funciones). Pero obtienes el registro de excepciones en el panel de Fabric/Crashlytics. Puede mirar estos registros y corregir las excepciones.

try {
    codeThatCouldRaiseError();
} catch (Exception e) {
    e.printStackTrace();
    Crashlytics.logException(e);
}
K Neeraj Lal
fuente
Si. Eso es lo que la gente está haciendo aquí, pero no estoy de acuerdo. Por eso publiqué la pregunta. ¿Puedes pensar en algo más lógico?
mallaudin
4
@mallaudin No publique código de ejemplo que distorsione el código sobre el que está preguntando. Puede cambiar drásticamente la respuesta que obtiene.
jpmc26
@ jpmc26 sí. Lo he visto en las respuestas.
mallaudin
0

Si bien estoy de acuerdo con las otras respuestas, hay una circunstancia que he encontrado repetidamente en la que este motivo es marginalmente tolerable. Supongamos que alguien escribió un poco de código para una clase de la siguiente manera:

private int foo=0;

    . . .

public int getFoo() throws SomeException { return foo; }

En esta circunstancia, el método 'getFoo ()' no puede fallar ; siempre habrá un valor legítimo del campo privado 'foo' que se devolverá. Sin embargo, alguien, probablemente por razones pedantes, decidió que este método debería declararse como potencialmente lanzador de una excepción. Si luego intenta llamar a este método en un contexto, por ejemplo, un controlador de eventos, que no permite que se lance una excepción, básicamente se verá obligado a usar esta construcción (incluso entonces, estoy de acuerdo en que al menos uno debería registrar la excepción solo en caso) . Siempre que tengo que hacer esto, siempre agrego al menos un gran comentario gordo 'ESTO NO PUEDE OCURRIR' junto a la cláusula 'catch'.

PMar
fuente