Using try/catch for preventing app from crashes

前端 未结 14 1841
你的背包
你的背包 2021-01-30 03:37

I have been working on an Android app which uses try/catch frequently to prevent it from crashing even on places where there is no need. For example,

A view

相关标签:
14条回答
  • 2021-01-30 04:12

    It's definitely a bad programming practice.

    From the current scenario, if there are hundreds of try catch like this, then you won't even know where the exception occurs without debugging the application, which is a nightmare if your application is in production environment.

    But you can include a logger so that you get to know when an exception is throws (and why). It won't change your normal workflow.

    ...
    try {
        View view = findViewById(R.id.toolbar);
    }catch(Exception e){
        logger.log(Level.SEVERE, "an exception was thrown", e);
    }
    ...
    
    0 讨论(0)
  • 2021-01-30 04:12

    It's bad practice to use catch(Exception e){} because you're essentially ignoring the error. What you probably want to do is something more like:

    try {
        //run code that could crash here
    } catch (Exception e) {
        System.out.println(e.getMessage());
    }
    
    0 讨论(0)
  • 2021-01-30 04:14

    Of course, there are always exceptions to rules, but if you need a rule of thumb - then you are correct; empty catch blocks are "absolutely" bad practice.

    Let's have a closer look, first starting with your specific example:

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

    So, a reference to something is created; and when that fails ... it doesn't matter; because that reference isn't used in the first place! The above code is absolutely useless line noise. Or does the person who wrote that code initially assume that a second, similar call would magically no longer throw an exception?!

    Maybe this was meant to look like:

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

    But again, what does this help?! Exceptions exist to communicate respectively propagate error situations within your code. Ignoring errors is rarely a good idea. Actually, an exception can be treated in ways like:

    • You give feedback to the user; (like: "the value you entered is not a string, try again"); or to engage in more complex error handling
    • Maybe the problem is somehow expected and can be mitigated (for example by giving a "default" answer when some "remote search" failed)
    • ...

    Long story short: the minimum thing that you do with an exception is to log/trace it; so that when you come in later debugging some problem you understand "OK, at this point in time that exception happened".

    And as others have pointed out: you also avoid catching for Exception in general (well, depending on the layer: there might be good reasons to have some catch for Exception, and even some kinds of Errors at the highest level, to make sure that nothing gets lost; ever).

    Finally, let's quote Ward Cunningham:

    You know you are working with clean code when each routine you read turns out to be pretty much what you expected. You can call it beautiful code when the code also makes it look like the language was made for the problem.

    Let that sink in and meditate about it. Clean code does not surprise you. The example you are showing to us surprises everybody looking at.

    Update, regarding the update that the OP asks about

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

    Same answer: doing that "all over the place" is also bad practice. Because this code is also surprising the reader.

    The above:

    • Prints error information somewhere. It is not at all guaranteed that this "somewhere" resembles a reasonable destination. To the contrary. Example: within the application I am working with, such calls would magically appear in our trace buffers. Depending on context, our application might pump tons and tons of data into those buffers sometimes; making those buffer prune every few seconds. So "just printing errors" often translates to: "simply loosing all such error information".
    • Then: you don't do try/catch because you can. You do it because you understand what your code is doing; and you know: I better have a try/catch here to do the right thing (see the first parts of my answer again).

    So, using try/catch as "pattern" like you are showing; is as said: still not a good idea. And yes, it prevents crashes; but leads to all kind of "undefined" behavior. You know, when you just catch an exception instead of properly dealing with it; you open a can of worms; because you might run into myriads of follow-on errors that you later don't understand. Because you consumed the "root cause" event earlier on; printed it somewhere; and that somewhere is now gone.

    0 讨论(0)
  • 2021-01-30 04:18

    Let me add my point of view, as a guy working in the corporate mobile development industry for more than a decade. First, some general tips on exceptions, most of them included in answers above:

    • Exceptions should be used for exceptional, unexpected or uncontrolled situations, not on a regular basis throughout the code.
    • A programmer must know the portions of code susceptible to throw exceptions and try-catch them, leaving the rest of the code as clean as possible.
    • Exceptions should not be left silent, as a general rule.

    Now, when you are not developing an app for yourself, but for a company or a corporation, it is common to face additional requirements on this topic:

    • "App crashes show a poor image of the company, so they are not acceptable". Then, careful development should be performed, and catching even improbable exceptions may be an option. If so, this must be done selectively and kept in reasonable limits. And notice that development is not all about lines of code, for instance, an intensive testing process is critical in these cases. However, unexpected behaviour in a corporate app is worse than crashing. So, whenever you catch an exception in your app, you must know what to do, what to show and how the app will behave next. If you cannot control that, better let the app crash.
    • "Logs and stack traces may dump sensitive information to the console. That might be used for an attacker, so for security reasons they cannot be used in a production environment". This requirement conflicts with the general rule for a developer not to write silent exceptions, so you have to find a way for it. For instance, your app could control the environment, so it uses logs and stack traces in non-production environments, while using cloud-based tools like bugsense, crashlitics or similar for production environments.

    So, the short answer is that the code you found it is not a good practice example, since it is hard and costly to maintain without improving the quality of the app.

    0 讨论(0)
  • 2021-01-30 04:20

    Yes, try/catch is used to prevent app from crashing but You certainly don't need try/catch for fetching a view from XML as depicted in your question.

    try/catch is generally used while making any http request, while parsing any String to URL, creating URL connections, etc. and also make sure to print stack trace. Not printing it doesn't make much sense in surrounding it with try/catch.

    0 讨论(0)
  • 2021-01-30 04:28

    While I agree with the other responses, there is one circumstance I have repeatedly encountered where this motif is marginally tolerable. Suppose someone wrote a bit of code for a class as follows:

    private int foo=0;
    
        . . .
    
    public int getFoo() throws SomeException { return foo; }
    

    In this circumstance, the 'getFoo()' method cannot fail - there will always be a legitimate value of the private field 'foo' to be returned. Yet someone - probably for pedantic reasons - decided that this method should be declared as potentially throwing an Exception. If you then try to call this method in a context - e.g an event handler - which does not allow an exception to be thrown, you are basically forced to use this construct (even then, I agree that one should at least log the exception just in case). Whenever I have to do this, I always at least add a big fat comment 'THIS CANNOT OCCUR' next to the 'catch' clause.

    0 讨论(0)
提交回复
热议问题