I have a try block and a catch block where NullPointerExceptions are caught. However, Lint warns that a statement in the try block may cause a NullPointerException, even though the exception will be caught. Why doesn't lint recognise that I have handled the possibility of the exception?
I am using Android Studio 3. Thanks.
As written here,
Programs must not catch java.lang.NullPointerException. A NullPointerException exception thrown at runtime indicates the existence of an underlying null pointer dereference that must be fixed in the application code. Handling the underlying null pointer dereference by catching the NullPointerException rather than fixing the underlying problem is inappropriate for several reasons. First, catching NullPointerException adds significantly more performance overhead than simply adding the necessary null checks [Bloch 2008]. Second, when multiple expressions in a try block are capable of throwing a NullPointerException, it is difficult or impossible to determine which expression is responsible for the exception because the NullPointerException catch block handles any NullPointerException thrown from any location in the try block. Third, programs rarely remain in an expected and usable state after a NullPointerException has been thrown. Attempts to continue execution after first catching and logging (or worse, suppressing) the exception rarely succeed.
Likewise, programs must not catch RuntimeException, Exception, or Throwable. Few, if any, methods are capable of handling all possible runtime exceptions. When a method catches RuntimeException, it may receive exceptions unanticipated by the designer, including NullPointerException and ArrayIndexOutOfBoundsException. Many catch clauses simply log or ignore the enclosed exceptional condition and attempt to resume normal execution; this practice often violates ERR00-J. Do not suppress or ignore checked exceptions. Runtime exceptions often indicate bugs in the program that should be fixed by the developer and often cause control flow vulnerabilities.
So, it appears like intentional behavior when Android Studio "ignores" NullPointerException catch blocks, and you should not be catching NullPointerException, instead just check for null.
See also this question.
The linter's job is to warn you of code that could be a problem. One of the built-in rules checks for dereferences that could cause NullPointerExceptions; it doesn't then check to see if this exception is caught.
However, I'm left wondering why you catch (NullPointerException e) instead of simply checking for null values and then proactively handling them.
Related
I went through this tutorial to learn about Firebase crash reporting. This is the code I've written to use it:
FirebaseApp.initializeApp(this);
try {
throw new FileNotFoundException();
} catch (FileNotFoundException ex) {
FirebaseCrash.logcat(Log.ERROR, TAG, "NPE caught");
String exception=ex.toString();
FirebaseCrash.report(ex);
}
In my Firebase console I can see my error. Everything is working perfect but I have one question. Is there any way to catch any exception wherever it occurs?
Firebase Crash Reporting will capture any Exception that does not get explicitly caught and crashes your app. You don't have to worry about that. Those are marked as Fatal exceptions in the dashboard. Exceptions you report are marked as non-fatal.
As a general rule, you should not try to suppress all exceptions, in order to prevent your app from crashing. Some exceptions indicate an unrecoverable situation or programming error, and your app process really should go away in order to prevent things from getting worse. Attempting to change this behavior could be worse for your users than seeing the Android crash dialog.
I just learned about Log.wtf ("What a Terrible Failure" lol) and I'm wondering when I should use it.
What is the difference between calling Log.wtf with an exception and letting an exception go unhandled (crash)?
How does it affect crash reports in the Google Play Developer Console?
I usually throw an IllegalStateException for unexpected conditions. Should I consider calling Log.wtf instead?
Edit:
See also: Under what circumstances will Android's Log.wtf terminate my app?
What Log.wtf does is write the exception and its stack trace in the log, and only that. It neither catches nor throws exceptions. So
The difference is the exception is logged or not. The exception remains unhandled.
It doesn't affect crash reports.
If you wish to log it, go ahead. But you'll want to keep throwing IllegalStateException.
EDIT
I tried debugging and stepping into Log.wtf but no luck.
What I've found is pretty much what is answered in the linked question. It seems that in the "default terrible failure handling" Log.wtf creates an internal exception (TerribleFailure) which wraps any given exception. Then it calls RuntimeInit.wtf(). Its javadoc says:
Report a serious error in the current process. May or may not cause
the process to terminate (depends on system settings).
I guess the behavior of Log.wtf is up to the device manufacturer. My Sony C6503 doesn't seem to raise any exception or kill the process.
Some open source reference:
https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/util/Log.java
https://android.googlesource.com/platform/frameworks/base/+/master/core/java/com/android/internal/os/RuntimeInit.java
Unhandled exceptions are not logged by default. Log.wtf may or may not crash the application. If you pass an exception to Log.wtf and it crashes, then you should get a stack trace similar to what you would get if the exception were not handled. After calling Log.wtf, you should (re)throw an exception if you want to ensure a crash (without catching it of course).
There may be specific use cases for Log.wtf, but if you are unsure, it's probably better to use Log.e instead.
I have a simple question. As we know, there are many places in the Android code where SecurityException is thrown for reasons. Is that reasonable that we catch the SecurityException and handle it but not let it crash the application?
If you catch every runtime exceptions, your application may not crash but it may not behave correctly as well. It might even crash at other points as well. The correct way is to handle those security failures. If you're handling a third-party API that can throw those security exception and it is not clear when those exceptions are thrown, then you may catch those exceptions. It is still better to understand why such situations occur - such as missing permissions, not having the required signature, etc.
I have to give a crash course of android to some internees. One of them ask me the common exception and their reason. So i decided to ask it for new developer as well as for myself.
for example
A NullPointerException is thrown at runtime whenever your program attempts to use a null as if it was a real reference. For example, if you write this:
String foo = null;
int length = foo.length(); // it is nullPointerException ..
What are other common exceptions occur in Android?
I think that the NetworkOnMainThreadException is often not understood and very common on this site to be asked questions about. It is also specific for Android. It is thrown when the applications tries to do network activity on the UI thread.
Another common Exception is ArrayIndexOutOfBoundsException which is thrown when one tries to access an element of the array which does not exist.
There are decades of common exceptions in Android. Read this documentation page http://developer.android.com/reference/java/lang/Exception.html. Some are more common than others, but it strictly depends on what you develop.
I would like to be able to determine, in case an exception occurs while the user is using my application, where exactly the exception took place. I'd like to do something similar ti printStackTrace() method. (So this is during build mode, not debug mode )
Currently I've put almost all my methods from all my classes inside a try-catch statement (each method has a try-catch statement which encompasses all it's instructions) and i can, at this point, display the "tree" or stack of methods if an exception occurs. But is there a way to determine either a line number of something to more precisely indicate where inside the method the exception occurred? Similar to what is displayed when you use printStackTrace().
I'm not really used with Exception handling, what is the best practice for doing this and can in be done?
EDIT
And one other thing. When i use printStackTrace() during build mode, where does it display the content, because Logcat isn't available? Can i retrieve that information and maybe do something with it?
OR
Even better, can i use getStackTrace() during build mode and convert the stuff there in String and maybe output it somewhere?
All the exceptions that are not handled by your code and make your app crash in release mode will appear in the android developper console, close to your app.
For this to work, you will need to retrace obfuscated stack traces.
About exception handling : I suggest you read this for instance. You are making a mistake about exception handling if you surround all your code by a try/catch block.
Exception handling is more subtile than that and is often influenced by design considerations (whether to treat exceptions locally or throw them back to the caller).
To sum up : in the core of your app : don't treat exception but throw them or let them be thrown, using the throws clause of your methods signatures. In the upper layers, closer to the UI, treat exceptions with try/catch and if an error occurs, make sure your app is in a stable state and display some usefull messages to users.
More details (but not that much) :
in the database layer : throw exception. You can still catch them to log them, but throw or rethrow them to tell caller that something went wrong.
in the business layer : catch them, make sure your business/domain model is in a stable state and recovers from the error, and throw them back to the caller.
in the UI layer : catch the exceptions and display some messages to users.