Validate function preconditions in android - java

Usually when writing a public method I do some error checking e.g.
public SomeResult processSomething (int i, List<String> items) {
if( i < 0 ) {
throw new IllegalArgumentException();
}
if(items == null) {
throw new NullPointerException();
}
etc
}
In android programming what is the standard approach for this? I noticed that when a fragment crashes the emulator goes to the previous fragment so from behavior shown to the user I guess it is ok. But what is the best way to deal with exceptional/error conditions?

The best practices here would be very similar to those used elsewhere in the Java world:
1. The first lines of a method are usually devoted to checking the validity of method arguments. The method should fail as quickly as possible in the event of an error.
When validating an argument, an Exception is thrown if the test fails. It's often one of these unchecked exceptions that are thrown:
IllegalArgumentException
NullPointerException
IllegalStateException
These are all derived from RuntimeException.
2. If every object parameter of every method in a class needs to be non-null in order to avoid throwing NullPointerException, then it's acceptable to state this once in the general class javadoc, instead of repeating it for each method.
References:
Preconditions, Postconditions, and Class Invariants.
EDIT:
To answer your question about "view specific for errors": while it is certainly possible to do that, the idea is that an Exception indicates the presence of programming errors in the code. Therefore, apps should be allowed to crash so that the user can report the error, and the developer thereby gets the error logs from the app's Play Store account. This way he can correct the sources of those errors. The process should continue till, hypothetically, the app is completely free of errors.

Nowadays we can use Kotlin Preconditions.kt:
data class User(val active: Boolean, val email: String?)
class UserHelper (private val user: User) {
fun mergeUsers(otherUser: User) {
// To verify enclosing class state we use "check methods".
// If check fails IllegalStateException will be thrown
checkNotNull(user.email) { "user email is null" }
check(user.active) { "user is not active" }
// To verify argument we use "require methods".
// If check fails IllegalArgumentException will be thrown
requireNotNull(otherUser.email) { "otherUser email is null" }
require(otherUser.active) { "otherUser is not active" }
// All the preconditions has been meet, so we can merge users
// ...
}
}

Related

Java: How to make lint respect the RuntimeException thrown from a inner function call?

I'm writing Android code using Android Studio, and it performs automatic lint checking when writing code.
I have a code snippet like this:
Obj fun() {
Obj o;
if (SOME_CONDITION) {
if (SOME_OTHER_CONDITION) {
o = SOMETHING;
} else {
panic();
}
} else {
panic();
}
return o;
}
where panic() is another function like this
void panic() {
throw new IllegalStateException();
}
However, the lint checker reports error that o may not have been initialized.
Apparently when going to the else branch, an IllegalStateException (a subclass of RuntimeException) is thrown, so the execution has terminated.
Note the o = SOMETHING; statement is a simplified description. The actual code is more complicated, and contains other condition checks.
Adding throws RuntimeException (or IllegalStateException) to panic() doesn't make any difference.
How can I tell the linter that it won't go wrong (without catching the exception and throw it again)?
A local variable must be definitely assigned
What you want is not possible. It's not merely a linter rule in Android studio, it's a language rule enforced by the compiler. JLS 16 states (emphasis added):
For every access of a local variable or blank final field x, x must be definitely assigned before the access, or a compile-time error occurs.
What you can do
Redefine panic():
RuntimeException panic() {
return new IllegalStateException();
}
Then use it like this to allow the compiler to verify that the flow of control never results in access to an un-assigned variable:
...
} else {
throw panic();
}
...
The panic() method could perform additional work, although logging and then throwing an exception is discouraged as it tends to cause redundant logging.
Lint is correct. Consider that "panic" could be changed in the future, or overridden by subclasses not to throw an exception. o will be uninitialized. If you really want lint to shut up about it, just initialize it.
A better option would be to move the declaration of o and the return statement to the branch where o=something. That's the only place it is really used, and it is obscuring the true intent of the code in other places. Instead of the return at the end of the function , throw an exception. If panic() really throws an exception, that line will never be called, but it should keep everyone happy.
In fact, depending on your real code, you may be able to simplify further:
Obj fun() {
if (SOME_CONDITION && SOME_OTHER_CONDITION) {
return SOMETHING;
}
panic();
throw new RuntimeException("We don't expect to get here");
}

Play Framework 2.3.1 Promise exception handling within inner class

What is the right approach in order to implement a correct exception handling within a WS API Request?
An example:
F.Promise<List<String>> modulesPromise = WS.url(requestUrl).setAuth(apiUser, apiPassword).get().map(
new F.Function<WSResponse, List<String>>() {
public List<String> apply(WSResponse response) {
List<String> modules = new ArrayList<>();
JsonNode json = response.asJson();
for (JsonNode node : json) {
modules.add(node.get("name").toString().replace("\"", StringUtils.EMPTY));
}
return modules;
}
}
);
modulesPromise.recover(new F.Function<Throwable, List<String>>() {
#Override
public List<String> apply(Throwable throwable) throws Throwable {
Logger.error("error", throwable);
return new ArrayList<>();
}
});
If an exception occurs in that case within the inner class, the exception ll be thrown further. Its the same problem with the method .onFailure(). Isn't it the best way to use a try catch block in order to catch potential exceptions? The recover and the onFailure method seems to be useless.
In your case, it appears that recover isn't going to do you much good. recover is used for provide a default value when the Promise fails (e.g. an exception is thrown inside it).
In this case you're operating on a List where calling node.get("name").toString() will throw an exception if name is not a field in the JsonNode. This will cause the Promise to fail entirely, and so the rest of your list is gone. You could wrap it in a try/catch, but it's not necessary.
Since node.get("name") returns null if there is no name, then you should just check for null before operating on it:
for (JsonNode node : json) {
if(node.get("name") != null)
modules.add(node.get("name").toString().replace("\"", StringUtils.EMPTY));
}
So the answer really is that it depends on your use case. Often, if an exception occurs within the Promise, you want it to fail. Then the rest of your code can handle it appropriately. However, if an exception can occur that would generally not affect the final result, then either catch or it handle it otherwise to prevent it from failing the Promise (checking the null, in this case).
You were thisclose. What you had was essentially:
promise = WS.get
.map;
promise.recover;
What you originally wanted is:
promise = WS.get
.map
.recover;
Your instinct was right: while try/catch handles exceptions synchronously, inline with the currently executing thread, methods like recover handle exceptions asynchronously while those promises are being evaluated/fulfilled. The key is that each promise is separate, and those methods that return a promise are actually returning a new promise.
The get promises to return the result of the HTTP call. The map promises to take that result and extract the "name" from each node. The recover promises that if there is an exception anywhere in the chain, it will return a new empty list instead. But in your example, that last promise isn't assigned/used anywhere, so no one is listening/watching/awaiting that promise; they are awaiting the map, which can fail (either itself or the get). Note that the recover code will still execute if there is an exception, but no one wants the result.
Whether to use recover or let the entire call fail is a separate question. For example, if you are composing a response from several other calls, maybe you could replace a failed third-party call with "not available", or simply omit the elements that did not work.
While recover returns a new promise, onFailure is void. It's what your example does: do something when there is an exception, but no one is dependent on it. For example, suppose you want to log whenever a third-party call fails. You could do that inside the recover -- log then return an empty list -- or you can do it separately: the recover returns the empty list, and the onFailure logs. That way, the functionality is more composable; and again, it's important that to differentiate the various promises:
promise = WS.get
.map;
promise.onFailure;
promise = promise.recover;

Is "throws Throwable" good practice

In the past I'd read tons of code with methods like:
public Object doSomething() throws Throwable {
...
}
Is it common practice to do that?
What are pros & cons?
throws Trowable seemed to me like the "Agent Orange" way of getting the Exception- matter done
EDIT
Handle expected Exceptions in the Method
Throw unexpected Exceptions (one by one)
Don't care of Errors
Is that the way to go?
You should not throw Throwable. Here's why.
Throwable is the top of the hierarchy of things that can be thrown and is made up of Exceptions and Errors. Since Errors by definition arise from unsalvagable conditions, it is pointless to include them in your method declaration. That leaves just Exception.
You should declare your method with throws Exception instead.
Note that the narrower the range of throws the better.
Declaring your method to be throws Exception is ok if your method doesn't generate the exceptions, but instead calls other code that is declared as throws Exception and you want exceptions to percolate up the call stack.
If your method is the generating the exception, then declare a narrower range, eg throws IOException, MyProcessingException, etc
That's a loaded question. This isn't so much about exception handling as it is about code readability.
It depends where you get your code samples from. Professionals prefer to be more specific when throwing out of a method. The main reason is that it keeps your APIs more readable. For example, if your method throws Throwable, that basically means anything could happen and your method doesn't want to deal with it, no matter what. But really, only a limited number of things could happen:
Whatever checked exceptions resulting from other calls you are making in your method
Whatever checked exceptions you are throwing on purpose based on your own assertions
Whatever unchecked exception you didn't plan for
Errors (java.lang.Error) that are more global to the JVM and the environment
By specifically stating the exceptions you want to throw, you are telling the users of your API about what they should beware of. For example, when you use InputStream, you'll notice most methods throw at least java.io.IOException, which gives you some useful information about what you should watch for.
When coding, as a general rule, you want to try to keep your APIs as expressive as possible. You've got essentially one line of code to show the public API of a method (i.e. its signature, annotations too I guess), so you want it completely expressive (return type, name, parameters, but also the thrown exceptions).
As far as catching the throwables and printing the stack trace, I'd say that you should not catch the exception unless you can do something about it. Instead, let it roll up the call stack until some class catches it to do something about it. Sometimes, it may roll all the way up to your main class, which I guess would have to catch it and print the stack trace as last resort. Basically, if you can't act upon the exception, then let it go up the call stack. Also it is extremely rare that you find yourself in a situation where you should silence an exception (i.e. catch it but do nothing about it). That's usually inviting problems when comes time to troubleshoot issues.
Here is a fun but interesting article around misuse of exception handling in general.
In some rare cases it is acceptable to throw Throwables. For example, #Around advices in Spring AOP are usually declared to throw a Throwable.
The following example is copied verbatim from Spring AOP docs:
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.ProceedingJoinPoint;
#Aspect
public class AroundExample {
#Around("com.xyz.myapp.SystemArchitecture.businessService()")
public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
// start stopwatch
Object retVal = pjp.proceed();
// stop stopwatch
return retVal;
}
}
Why is doBasicProfiling declared to throw a Throwable? Because the original method (i.e. the execution join point), might throw an Error, RuntimeException, or a checked exception. So it only makes sense to declare doBasicProfiling to throw a Throwable.
Functionally, it is equivalent with throws Exception, since errors are unchecked.
I see no reason to declare a method to throw Throwable. However, this doesn't mean that catch and printStackTrace is a good alternative.
Usually, you want to catch throwables where you can do something sensible with them.
Code that throws a throwable you don't expect should explode gloriously, so you can see the error and fix the bug.
Is it common practice to do that?
In the JDK it is rare. This is mostly used when it is not clear how to handle checked exceptions.
What are pros & cons?
The pros is that you get your code to compile without worrying about checked exception.s
The cons is that exception you should be handling are being ignored.
Isn't it better to catch and printStackTrace()?
Unhandled exception are usually printed anyway so catching them doesn't help much.
You should catch an exception when you can add some value by doing so and add the exception to the throws clause when you can't.
It is really debatable matter.
Having method throwing too many exceptions will result in lot of error handling code. Some times it is not intended.
But because I don't like too many exception in signature does not mean that Lets use Parent of all exceptions and we are done!! It will not work.
What one can do is categorise exceptions such as BusinessException,ServiceException so that if you have a business rule which says that minimum balance in account can not be less than say 100$ then InsufficientBalance exception will be generated which will be child of BusinessException
so you method will be like
public Object doSomething() throws BusinessException {
if(!hasMinimumbalance())
{
throw new InsufficientBalance(ErrorCode);
}
}
What this will do is club related exceptions together and whenever API user wants to detect exception specific error then he can do it, else generic error handling is possible.
The core point here is on the UI you should display to the user that You have run out of balance and you can not withdraw money
You can say on the larger aspect to display human readable form of error it is really necessary to have separation of exceptions.
Are you asking about Throwable specifically? If so, then it's not good practice. It doesn't provide any useful information to class (method) user.
Throwing (and catching) Throwable (or Exception) is generally bad practice because it 'blankets' any specific exceptions you might want to catch. Then you would have to resort to ugliness like below:
public void myMethod() throws Throwable {
if (x) {
throw new MyException1();
}
if (y) {
throw new MyException2();
}
}
public void callingMethod() {
try {
myMethod();
}
catch(Throwable t) {
if (t instanceof MyException1) {
// handle exception 1
}
else if (t instanceof MyException2) {
// handle exception 2
}
else {
// handle other exceptions
}
}
}
Which is error prone (and flagged by CheckStyle as a code violation). It is much preferrable to have code like this:
public void myMethod() throws MyException1, MyException2 {
if (x) {
throw new MyException1();
}
if (y) {
throw new MyException2();
}
}
public void callingMethod() {
try {
myMethod();
}
catch(MyException1 e) {
// handle exception 1
}
catch(MyException2 e) {
// handle exception 2
}
}
Handling an exception just by calling printStackTrace() is usually not a good idea. printStackTrace() sends the stacktrace to standard error, which may not be read at all. A better option is to use the application's logging facility (like log4j) to report the exception. Even then, just logging it might no be enough.
My rule of thumb is:
If you can handle an exception locally, do so. For example when parsing a String as an Integer you could catch the NumberFormatException and return a default value:
prvate int parseAmount(String amountValue) {
int amount;
try {
amount = Integer.parseInt(amountValue);
}
catch(NumberFormatException e) {
// default amount
amount = 0;
}
return amount;
}
If you cannot handle an exception locally, consider if you should expose the exception type that is being thrown. If this type is some obscure (implementation-dependent) type, then wrapping it in your own generic exception type is probably a good idea:
private Customer getCustomer(int customerId) throws ServiceException {
try {
return customerService.getCustomer(customerId);
}
catch(CustomerServiceSpaghettiTangledException e) {
throw new ServiceException("Error calling the customer service", e);
}
}
Here 'ServiceException' is a subclass of Exception created by you. Spring also offers an exception hierarchy specifically for this purpose.
By wrapping the exception you hide the implementation details, making your service layer much simpler to use.
If you decide to throw an exception from your method, you will need to handle it 'higher up' in the callstack. This can be a generic error page in your web application stating that something went wrong and possibly providing an error message or code. In some cases the higher level code can attempt a retry or possibly an alternative way to obtain the required result.
The only use case I can think of would be for test code like unit tests. But Adam's counterpoint still stands "If so, then it's not good practice. It doesn't provide any useful information to class (method) user."

Should I create a custom exception type so my code is easier to unit test

In my unit test, I test a method for an expected RuntimeException and I want to distinct those thrown by my component from ones thrown by the code called in the method.
Creating a custom exception type is unnecessary and does not solve the problem if the method throws the same exception type but for different reasons, e.g. InvalidArgumentException.
Looks like the only way to tell them is the message or the error code. Because the message can be changed during development, the error code seems the only reliable option.
What is the best practice for creating of system of error codes so they don't conflict with ones of external packages, eg. third party libraries?
Creating a custom exception type is unnecessary and does not solve the
problem if the method throws the same exception type but for different
reasons, e.g. InvalidArgumentException.
Why do you think it's unnecessary? This is what you should do. Derive your own custom exception classes, throw their instances from your code and catch them outside (in your unit tests). The catch statement can be repeated in anticipation of multiple different exception classes:
try {
// something
} catch (MySpecificException e) {
// you know that your code threw this
} catch (Exception e) {
// this is coming from somewhere else
}
--Edit--
Sorry, I didn't see the java tag. Even though the following example uses PHP constructs, the principles should still apply.
--Original--
I use custom exception codes in only a few, very specific cases, and I store these codes in a custom exception class which extends the default exception class. They are stored in the class as constants, as the value doesn't really matter, but the context does.
Consider:
class CoreLib_Api_Exception extends Exception
{
const EXCEPTION_FORMAT = '%s (%s): %s';
const CODE_FILE_DNE = 100;
const CODE_DIR_BASE_EQUALS_REMOVE = 101;
const CODE_XML_READER_UNABLE_TO_OPEN = 200;
const CODE_XML_READER_UNABLE_TO_READ = 201;
}
// Example usage
class CoreLib_Api_Reader
{
protected function getReader()
{
$reader = new CoreLib_Api_Xml_Reader();
if (!#$reader->open($this->getFileUri())) {
$e = new CoreLib_Api_Exception(sprintf('Could not open %s for parsing', $this->getFileUri()), CoreLib_Api_Exception::CODE_XML_READER_UNABLE_TO_OPEN);
throw $e;
}
}
}
// Calling code
try {
$reader = CoreLib_Api_Reader();
$reader->setFileUri($fileUri);
$reader->getReader();
} catch (Exception $e) {
// If code is anything other than open, throw it
if ($e->getCode() !== CoreLib_Api_Exception::CODE_XML_READER_UNABLE_TO_OPEN) {
throw $e;
}
$e = null;
$reader = null;
}
By using the exception code, I can check to determine if the reader is unable to open the file, if so ignore the exception and move on, otherwise throw the exception and break the flow.
And if one of my exception codes collides with a third party exception code, it doesn't matter, as I mentioned before, using constants, the context will dictate which code I want to match on.
I test a method for an expected RuntimeException
I think this is a mistake. A RuntimeException should be used only for indicating bugs in the code that the code itself can detect. Testing should test only for specified (defined) behaviour. But when there is a bug in some code, its behaviour is undefined (who knows where the bug could be or what it might do). So there is no point in trying to specify what RuntimeExceptions some code should throw; that is like specifying how the code should behave "in the presence of a bug". Throwing particular RuntimeExceptions with particular messages should be seen as a courtesy to the maintenance programmer (who is likely to be you).

JUnit4 fail() is here, but where is pass()?

There is a fail() method in JUnit4 library. I like it, but experiencing a lack of pass() method which is not present in the library. Why is it so?
I've found out that I can use assertTrue(true) instead but still looks unlogical.
#Test
public void testSetterForeignWord(){
try {
card.setForeignWord("");
fail();
} catch (IncorrectArgumentForSetter ex){
}
// assertTrue(true);
}
Call return statement anytime your test is finished and passed.
As long as the test doesn't throw an exception, it passes, unless your #Test annotation specifies an expected exception. I suppose a pass() could throw a special exception that JUnit always interprets as passing, so as to short circuit the test, but that would go against the usual design of tests (i.e. assume success and only fail if an assertion fails) and, if people got the idea that it was preferable to use pass(), it would significantly slow down a large suite of passing tests (due to the overhead of exception creation). Failing tests should not be the norm, so it's not a big deal if they have that overhead.
Note that your example could be rewritten like this:
#Test(expected=IncorrectArgumentForSetter.class)
public void testSetterForeignWord("") throws Exception {
card.setForeignWord("");
}
Also, you should favor the use of standard Java exceptions. Your IncorrectArgumentForSetter should probably be an IllegalArgumentException.
I think this question needs an updated answer, since most of the answers here are fairly outdated.
Firstly to the OP's question:
I think its pretty well accepted that introducing the "expected excepetion" concept into JUnit was a bad move, since that exception could be raised anywhere, and it will pass the test. It works if your throwing (and asserting on) very domain specific exceptions, but I only throw those kinds of exceptions when I'm working on code that needs to be absolutely immaculate, --most APIS will simply throw the built in exceptions like IllegalArgumentException or IllegalStateException. If two calls your making could potentitally throw these exceptions, then the #ExpectedException annotation will green-bar your test even if its the wrong line that throws the exception!
For this situation I've written a class that I'm sure many others here have written, that's an assertThrows method:
public class Exceptions {
private Exceptions(){}
public static void assertThrows(Class<? extends Exception> expectedException, Runnable actionThatShouldThrow){
try{
actionThatShouldThrow.run();
fail("expected action to throw " + expectedException.getSimpleName() + " but it did not.");
}
catch(Exception e){
if ( ! expectedException.isInstance(e)) {
throw e;
}
}
}
}
this method simply returns if the exception is thrown, allowing you to do further assertions/verification in your test.
with java 8 syntax your test looks really nice. Below is one of the simpler tests on our model that uses the method:
#Test
public void when_input_lower_bound_is_greater_than_upper_bound_axis_should_throw_illegal_arg() {
//setup
AxisRange range = new AxisRange(0,100);
//act
Runnable act = () -> range.setLowerBound(200);
//assert
assertThrows(IllegalArgumentException.class, act);
}
these tests are a little wonky because the "act" step doesn't actually perform any action, but I think the meaning is still fairly clear.
there's also a tiny little library on maven called catch-exception that uses the mockito-style syntax to verify that exceptions get thrown. It looks pretty, but I'm not a fan of dynamic proxies. That said, there syntax is so slick it remains tempting:
// given: an empty list
List myList = new ArrayList();
// when: we try to get the first element of the list
// then: catch the exception if any is thrown
catchException(myList).get(1);
// then: we expect an IndexOutOfBoundsException
assert caughtException() instanceof IndexOutOfBoundsException;
Lastly, for the situation that I ran into to get to this thread, there is a way to ignore tests if some conidition is met.
Right now I'm working on getting some DLLs called through a java native-library-loading-library called JNA, but our build server is in ubuntu. I like to try to drive this kind of development with JUnit tests --even though they're far from "units" at this point--. What I want to do is run the test if I'm on a local machine, but ignore the test if we're on ubuntu. JUnit 4 does have a provision for this, called Assume:
#Test
public void when_asking_JNA_to_load_a_dll() throws URISyntaxException {
//this line will cause the test to be branded as "ignored" when "isCircleCI"
//(the machine running ubuntu is running this test) is true.
Assume.assumeFalse(BootstrappingUtilities.isCircleCI());
//an ignored test will typically result in some qualifier being put on the results,
//but will also not typically prevent a green-ton most platforms.
//setup
URL url = DLLTestFixture.class.getResource("USERDLL.dll");
String path = url.toURI().getPath();
path = path.substring(0, path.lastIndexOf("/"));
//act
NativeLibrary.addSearchPath("USERDLL", path);
Object dll = Native.loadLibrary("USERDLL", NativeCallbacks.EmptyInterface.class);
//assert
assertThat(dll).isNotNull();
}
I was looking for pass method for JUnit as well, so that I could short-circuit some tests that were not applicable in some scenarios (there are integration tests, rather than pure unit tests). So too bad it is not there.
Fortunately, there is a way to have a test ignored conditionally, which actually fits even better in my case using assumeTrue method:
Assume.assumeTrue(isTestApplicable);
So here the test will be executed only if isTestApplicable is true, otherwise test will be ignored.
There is no need for the pass method because when no AssertionFailedException is thrown from the test code the unit test case will pass.
The fail() method actually throws an AssertionFailedException to fail the testCase if control comes to that point.
I think that this question is a result of a little misunderstanding of the test execution process. In JUnit (and other testing tools) results are counted per method, not per assert call. There is not a counter, which keeps track of how many passed/failured assertX was executed.
JUnit executes each test method separately. If the method returns successfully, then the test registered as "passed". If an exception occurs, then the test registered as "failed". In the latter case two subcase are possible: 1) a JUnit assertion exception, 2) any other kind of exceptions. Status will be "failed" in the first case, and "error" in the second case.
In the Assert class many shorthand methods are avaiable for throwing assertion exceptions. In other words, Assert is an abstraction layer over JUnit's exceptions.
For example, this is the source code of assertEquals on GitHub:
/**
* Asserts that two Strings are equal.
*/
static public void assertEquals(String message, String expected, String actual) {
if (expected == null && actual == null) {
return;
}
if (expected != null && expected.equals(actual)) {
return;
}
String cleanMessage = message == null ? "" : message;
throw new ComparisonFailure(cleanMessage, expected, actual);
}
As you can see, in case of equality nothing happens, otherwise an excepion will be thrown.
So:
assertEqual("Oh!", "Some string", "Another string!");
simply throws a ComparisonFailure exception, which will be catched by JUnit, and
assertEqual("Oh?", "Same string", "Same string");
does NOTHING.
In sum, something like pass() would not make any sense, because it did not do anything.

Categories

Resources