Having generic AsyncTask handle any Exception - java

I have created an generic AsyncTask class, so that I can catch all Exceptions thrown when task method is executed:
public abstract class Poc<ParamType, ReturnType>
extends AsyncTask<ParamType, String, ReturnType> {
abstract ReturnType task(ParamType... param);
#Override
protected ReturnType doInBackground(ParamType... param) {
try {
return task(param);
} catch (Exception e) {
// Make some Toast display the exception.
}
return null;
}
}
I try to implement the above class by doing some thing like:
public class Use {
public static void runIt() {
new Poc<String, Boolean>() {
#Override
Boolean task(String... param) {
return SomeObject.someMethodThatCanThrowAnException(param);
}
}.execute("Some String");
}
}
However, it keeps complaining about wanting me to add try/catch statements. Even when I know that task will only be called from doInBackground which wraps it.
Can I somehow suppress this? Or what is the proper approach without having to add try/catch to every single class that subclasses Poc?

As the compiler is trying to tell you, you need to declare your function as being able to throw things using throws Exception.
In this case, you would want the abstract method to be able to throw.

Related

How to new an InvocationException in Java?

How could I new an InvocationException in Java ?
InvocationException needs an ObjectReference in its constructor, I don't know how to create one.
Do you mean InvocationTargetException?
From the API: Is a checked exception that wraps an exception thrown by an invoked method or constructor.
Not sure what you try to achieve, maybe share some code and describe your intentions, however if you want to extend this exception then:
package .....;
import java.lang.reflect.InvocationTargetException;
public class SampleException extends InvocationTargetException {
protected SampleException() {
super();
}
public SampleException(Throwable target) {
super(target);
}
public SampleException(Throwable target, String s) {
super(target, s);
}
#Override
public Throwable getTargetException() {
return super.getTargetException();
}
#Override
public Throwable getCause() {
return super.getCause();
}
}
Maybe you want to override getTargetException with something specific to your requirement to catch InvocationTargetException and rethrow with your specific exception?
try{
.....
}catch(InvocationTargetException e){
//Do something with e?
throw new SampleException(); //Rethrow?
}
As I said not much information given.

Java 8 - throw multiple generic checked exceptions in lambda

In a project I am working at, I have found a class which wraps all methods of its super-class in some elaborate exception handling. It looks similar to that:
public void method1() throws ExceptionA {
String exceptionString = "";
try {
super.method1();
} catch (ExceptionA e) {
exceptionString = // <convert the exception to string in an elaborate way>
throw e;
} finally {
// <an elaborate logger call which uses value of exceptionString>
}
}
public void method2() throws ExceptionB, ExceptionC {
String exceptionString = "";
try {
super.method2();
} catch (ExceptionB | ExceptionC e) {
exceptionString = // <convert the exception to string in elaborate way>
throw e;
} finally {
// <an elaborate logger call which uses value of exceptionString>
}
}
// ... <a bunch of other methods like this>
I immediately though "Wow, how could would it be to have one generic wrapper and just call it in every of these methods. The class would be like 10x shorter!".
So I got to work.
This is where I got stuck:
private interface ThrowingMethod<E extends Exception> {
void run() throws E;
}
public <E extends Exception> void wrapMethod(ThrowingMethod<E> method) throws E {
String exceptionString = "";
try {
method.run();
} catch (Exception e) {
exceptionString = // <convert the exception to string in an elaborate way>
throw e;
} finally {
// <an elaborate logger call which uses value of exceptionString>
}
}
public void method1() throws ExceptionA {
wrapMethod(super::method1); // works
}
public void method2() throws ExceptionB, ExceptionC {
wrapMethod(super::method2); // Error in Eclipse: "Unhandled exception type Exception"
}
// ... <a bunch of other methods like this>
In conclusion, this approach works for methods that throws only one type of checked exception. When method throws multiple checked exceptions, Java assumes that the exception type is Exception.
I tried to add more generic parameters to ThrowingMethod and wrapMethod but it doesn't change anything.
How can I get a functional interface to work with multiple generic exceptions?
When you expand your interface to use two type variables, i.e.
private static interface ThrowingMethod<E1 extends Exception,E2 extends Exception> {
void run() throws E1, E2;
}
public <E1 extends Exception,E2 extends Exception>
void wrapMethod(ThrowingMethod<E1,E2> method) throws E1,E2 {
// same as before
}
the rules regarding the type inference do not change and they are the same for both type variables. E.g. you can still use
public void method1() throws ExceptionA {
wrapMethod(super::method1);
}
as before, as the compiler simply infers the same single exception type for both type variables.
For the method declaring two exceptions, it won’t pick up one for the first type variable and the other for the second; there is no rule which could tell the compiler which exception to use for which type variable.
But you can help the compiler out in this case, e.g.
public void method2() throws ExceptionB, ExceptionC {
wrapMethod((ThrowingMethod<ExceptionB, ExceptionC>)super::method2);
}
which is the best you can get with this approach.
So your goal is just to wrap a bunch of methods with logging? A typical way to handle this is with AOP. You'd just create a single pointcut that matches all those methods, and you wouldn't have a bunch of repeated boilerplate. No need for those interfaces or wrapping methods.

Method calling issue

I came into this whilst spending my night programming.
//Reader class isn't java.io but it's from third party library
public class ACR122U extends Reader {
// This method is called from outside
// This method overrides method of the Reader class
#Override
public void open(UsbDevice device) {
new OpenTask().execute(device);
}
private class OpenTask extends AsyncTask<UsbDevice, Void, Exception> {
#Override
protected Exception doInBackground(UsbDevice... params) {
Exception result = null;
try {
// There the problem (recursion) happens
// I don't want to call ACR122U.open() but Reader.open()
// I cannot call super.open() /super of OpenTask class is AsyncTask/
open(params[0]);
} catch (Exception e) {
result = e;
}
return result;
}
}
}
and I'm wondering if it's possible to solve the problem without changing name of open() method.
Any idea?
PS: Newbie here.
The syntax for what you want to do is:
ACR122U.super.open(params[0]);
However, if you're talking about java.io.Reader, this isn't going to work because the Reader class doesn't define an open() method; certainly not an open(UsbDevice) method.

How I can get a list of all possible exceptions of function

How I can scan my code and get all possible throws MyException errorCode's of execute() function?
Errors const:
public enum ErrorId {
OK(1),
REPORT_LIMIT(2),
NOT_UNIQUE_FIELD(3),
INCORRECT_PROPERTY(4);
private int id;
ErrorId(int id) {
this.id = id;
}
}
For example I have 'MyException' :
public class MyException extends Exception {
#Getter
protected final ErrorId errorCode;
public MyException(ErrorId errorCode) {
this.errorCode = errorCode;
}
}
And class with method:
public class MyClass {
public void execute() throws MyException {
//do something 1
...
if(isSomethingWrong1) throw new MyException(ErrorId.REPORT_LIMIT);
executeMethod2();
//do something N
if(isSomethingWrongN) throw new MyException(ErrorId....);
}
public void executeMethod2() throws MyException {
// ...
throw new MyException(ErrorId....)
// ...
}
}
I don't think there's an answer here that you'll like.
Reflection won't work in this case, because it's concerned with types, not values. The compiler can't help you here, either, because if the error code comes in through a variable, then at runtime, all bets are off -- the value could be any possible value of the type you're using. If you're using an enum for the code value, then you have a known list of all possible values, but you won't know which ones are actually used in any particular function without reading that function. A static analysis tool may be of use here, but you'd need to continue running it over time to keep this information up to date.
However, all is not lost. As I said in my second comment, you have another choice -- extract subclasses. Let's consider this definition of your Exception class.
public abstract class MyException extends Exception {
#Getter
protected final ErrorId errorCode;
public MyException(ErrorId errorCode) {
this.errorCode = errorCode;
}
}
It's the same as yours is now, but it's abstract. This class is open for extension. So we could create a subclass ReportLimitException like this:
public class ReportLimitException extends MyException {
public ReportLimitException() {
super(ErrorId.REPORT_LIMIT);
}
}
and another like this, for example:
public class DuplicateFieldException extends MyException {
public DuplicateFieldException() {
super(ErrorId.NOT_UNIQUE_FIELD);
}
}
Now, any given method can advertise which particular exceptions it uses via its throws clause. This is, in fact, why that clause exists.
public void execute() throws ReportLimitException, DuplicateFieldException {
//do something 1
//...
if(isSomethingWrong1) throw new ReportLimitException();
executeMethod2();
//do something N
if(isSomethingWrongN) throw new DuplicateFieldException();
}
At this point, if you advertise the exceptions explicitly, you'll have achieved your goal, at the cost of some potentially long throws clauses (which should actually be a hint to you that the method may be doing too much work anyway). Alternatively if you don't want to advertise every exception like that, you could also use your IDE's "find references" feature to locate every place where those exceptions are created (look for references to the constructors).
And the calling code doesn't even have to be aware of the change. It can continue using code like this:
try {
// stuff that might throw any of your exceptions
} catch (MyException ex) {
switch (ex.getErrorCode()) {
// handle the cases...
}
}

java exception catching in a different class than throwing

I have been working on a code that does 2 things:
Has a class that performs computations (logic)
has a class that displays the result.
I am wondering if it is possible to use try/catch statements in the Display class, where I would attempt to catch exceptions originating in the logic class.
Where Display would execute a line similar to logic.execute(input);
I was able to create a custom exception class where the following is placed in display class:
try{
logic.execute(input);
}catch(CustomException e){
//print statements
}
However I would like to be able to print exactly the error that occured, such as NullPointerException.
When i say print, i mean output in console. (but it must originate from display class)
If such a monstrosity is possible, please let me know.
Thank You guys!
Yes, it's possible.
You will need your custom exception class to extend RuntimeException instead of Exception, or the compiler will complain that you are not catching the exception that you throw.
See this post: Throwing custom exceptions in Java
Simple working example:
public class ExceptionTest
{
public static void main(String[] args)
{
SomeClass myObject = new SomeClass();
myObject.testFunction();
}
}
public class SomeClass
{
private SomeOtherClass someOther = new SomeOtherClass();
public void testFunction()
{
try{
someOther.someOtherFunction();
}
catch(Exception e){
System.out.println(e.toString());
}
}
}
public class SomeOtherClass
{
public void someOtherFunction()
{
throw new CustomException("This is a custom exception!");
}
}
public class CustomException extends RuntimeException
{
public CustomException(String message)
{
super(message);
}
}

Categories

Resources