Java re-throw Exception - java

I have a Project with two classes. One Object class and one GUI class.
I would like to throw my own declared Exception if an error occurs.
I have two methods:
public class getValueClass {
private List<Value> liste;
public List<Value> getValues() {
try {
liste = this.getVal();
} catch (ValueException ex) {
System.out.println("EXCEPTION!! " + ex.getMessage());
ex.printStackTrace();
}
return liste;
}
public List<Value> getVal() throws ValueException
{
liste = null;
try {
// initialize list
// do some stuff
//test exception
if(1 == 1)
{
throw new Exception();
}
} catch (Exception ex) {
throw new ValueException("QWE " + ex);
}
return liste;
}
}
Now the exception is thrown and I catch the exception in my getValues Method and print the Message/Stack
But I call the Method getValues in my GUI-Class and I want to catch the Exception there and print some Information in my dialog!
GUI:
public void myMethod()
{
try
{
l = cs.getValues();
}
catch(Exception ex)
{
System.out.println("TEST " + ex.getMessage());
}
}
But I don't get there because I already catch it in the getValues() method.
Is it possible to make it like this WITHOUT adding throws at method declaration for getValues() method? ( I get this method from an interface and will not change it)

You could throw an unchecked RuntimeException such as IllegalArgumentException or customized RuntimeException subclass.
public List<Value> getValues() {
try {
liste = this.getVal();
} catch (ValueException ex) {
throw new IllegalArgumentException(ex.getMessage(), ex);
}
return liste;
}

There is a way to do what you want, but I advise against it depending on your intended purpose of ValueException, as it could be the source of future bugs
You can have ValueException extend RuntimeException. The RuntimeException set of exceptions, as the name implies, are thrown at runtime and are not declared at compile time, and need to be explicitly caught. This way you wouldn't have to add a throws declaration to the getValues() method, but would still catch it in your main method.
Disclaimer explained:
The reason I am not a fan of this idea (and RuntimeExceptions in general) is because they're uncaught until explicitly looked for. This in my mind doesn't make for easy-to-use code, and while it has it's very handy uses, I don't feel right using them because of the uncertainty they carry
Again, this is my opinion, not Java's

Related

How to eliminate the duplicate try-catch code in similar methods?

I have the following insert/update methods in my service:
#Override
public void insertEntity(Entity entity) {
try {
entityDao.insert(entityMapper.entityToEntityDO(entity));
} catch (DataIntegrityViolationException ex){
if(ex.getCause() instanceof SQLIntegrityConstraintViolationException) {
SQLIntegrityConstraintViolationException violationEx = (SQLIntegrityConstraintViolationException) ex.getCause();
if(violationEx.getErrorCode() == 1048 && "23000".equals(violationEx.getSQLState())) {
throw new FieldCannotBeNullException(violationEx.getMessage());
}
}
throw ex;
}
}
#Override
public void updateEntity(Entity entity) {
try {
entityDao.update(entityMapper.entityToEntityDO(entity));
} catch (DataIntegrityViolationException ex){
if(ex.getCause() instanceof SQLIntegrityConstraintViolationException) {
SQLIntegrityConstraintViolationException violationEx = (SQLIntegrityConstraintViolationException) ex.getCause();
if(violationEx.getErrorCode() == 1048 && "23000".equals(violationEx.getSQLState())) {
throw new FieldCannotBeNullException(violationEx.getMessage());
}
}
throw ex;
}
}
As you can see, the actual logic of insertEntity and updateEntity is very simple. In order to throw a custom Exception, I did some database error code check. Since the two methods all need this kind of checking, the code duplicated in both methods, which is obviously a code smell.
How can I eliminate this kind of code duplication?
Extract the common catch-block to a method which throws DataIntegrityViolationException.
You can create Interface like this:
public interface ConsumerWithException<T, V extends Exception> {
/**
* Performs this operation on the given argument.
*
* #param t the input argument
*/
void accept(T t) throws V;
}
Use it a private method like:
private void action(ConsumerWithException<Entity, DataIntegrityViolationException> doAction, Entity entity){
try {
doAction.accept(entity);
} catch (DataIntegrityViolationException ex){
if(ex.getCause() instanceof SQLIntegrityConstraintViolationException) {
SQLIntegrityConstraintViolationException violationEx = (SQLIntegrityConstraintViolationException) ex.getCause();
if(violationEx.getErrorCode() == 1048 && "23000".equals(violationEx.getSQLState())) {
throw new FieldCannotBeNullException(violationEx.getMessage());
}
}
throw ex;
}
}
You can put the code inside the catch block into a separate method.
Alternatively, You can catch Exception and write a handler method to handle the exceptions if in future you expect to handle multiple exceptions there.
You can declare your methods to throw the exception, then try/catch in one place where your methods are called. For example:
public void insertEntity(Entity entity) throws DataIntegrityViolationException {}
public void updateEntity(Entity entity) throws DataIntegrityViolationException {}
try {
insertEntity(entity);
updateEntity(entity);
catch (DataIntegrityViolationException e) {
// handle exception
}

Suppressed Exceptions in Java SE7

I am trying to understand suppressed Exceptions in Java SE7, I posted 2 examples below, They are similar, In the following example, I was under the impression that when new "main Exception" happens, the suppressed ones get ignored, for instance I was expecting the output to be "java.lang.RuntimeException: y", However the answer is:
java.lang.RuntimeException: y
suppressed java.lang.RuntimeException: a
Here is the code:
class Animal implements AutoCloseable{
#Override
public void close() {
throw new RuntimeException("a");
}
}
public class ExceptionsDemo {
public static void main(String[] args) throws IOException {
try(Animal a1 = new Animal();){
foo();
}
catch(Exception e){
System.err.println(e);
for(Throwable t : e.getSuppressed()){
System.err.println("suppressed "+ t);
}
}
}
static void foo() {
try {
throw new RuntimeException("x");
} catch (Exception e) {
throw new RuntimeException("y");
}
}
}
My understanding was that after tryWithResources clause, "a" is main Exc, then in foo(), x becomes main exc while a gets suppressed, but in catch, I thought y will become the solo main exc and will ignore all other exceptions including suppressed ones? Like this second example, It does what I just mentioned, it outputs java.lang.RuntimeException: c with no suppressed exceptions.
public class ExceptionDemo2 {
class Animal implements AutoCloseable{
#Override
public void close() {
throw new RuntimeException("a");
}
}
public static void main(String[] args) {
try{
new ExceptionDemo2().go();
}
catch(Exception e){
System.err.println(e);
for(Throwable t : e.getSuppressed()){
System.err.println("suppressed "+ t);
}
}
}
void go(){
try(Animal a = new Animal()){
throw new IOException();
}catch(Exception e){
throw new RuntimeException("c");
}
}
}
output: java.lang.RuntimeException: c
Your example
try(Animal a1 = new Animal();){
foo();
}
catch(Exception e){
System.err.println(e);
for(Throwable t : e.getSuppressed()){
System.err.println("suppressed "+ t);
}
}
terminates because foo() throws a RuntimeException (y). That's the target of the catch. Because execution leaves the try block, all declared resources are closed. While closing the Animal instance, another RuntimeException (a) is thrown. That one is suppressed because it wasn't the root cause.
The translation of try-with-resources to a try-catch-finally block is explained in the JLS, here.
The meaning of a basic try-with-resources statement:
try ({VariableModifier} R Identifier = Expression ...)
Block
is given by the following translation to a local variable declaration
and a try-catch-finally statement:
{
final {VariableModifierNoFinal} R Identifier = Expression;
Throwable #primaryExc = null;
try ResourceSpecification_tail
Block
catch (Throwable #t) {
#primaryExc = #t;
throw #t;
} finally {
if (Identifier != null) {
if (#primaryExc != null) {
try {
Identifier.close();
} catch (Throwable #suppressedExc) {
#primaryExc.addSuppressed(#suppressedExc);
}
} else {
Identifier.close();
}
}
}
}
where
If the resource specification declares one resource, then
ResourceSpecification_tail is empty (and the try-catch-finally
statement is not itself a try-with-resources statement).
Your code above basically translates to something like
try {
final Animal a1 = new Animal();
Throwable thr = null;
try {
foo();
} catch (Throwable root) {
thr = root;
throw root;
} finally {
if (a1 != null) {
if (thr != null) {
try {
a1.close();
} catch (Throwable suppressed) {
thr.addSuppressed(suppressed); // <<<<<< suppressing the failure of 'close'
}
} else {
a1.close();
}
}
}
} catch (Exception e) {
System.err.println(e);
for (Throwable t : e.getSuppressed()) {
System.err.println("suppressed " + t);
}
}
This is confusing because it mixes try-with-resources with the exception-masking behavior that try-with-resources is supposed to cure.
Also it seems like you're not aware of what it means for an exception to be suppressed. Suppressed means that the exception is tacked on to an existing exception, rather than being thrown, and in the progress causing the exception thrown within the try-block getting lost (the usual term is "masked").
Exception-masking means that an exception thrown from the finally or catch block results in any exception thrown from within the try block getting discarded. Since the exceptions thrown on in the try-blocks are usually descriptive of what your error is, and the exceptions thrown on close are usually uninteresting, this is a bad thing; try-with-resources was created in order to try to reduce the prevalence of this problem.
So in your first example, foo is called on a1 within the try block, within foo the exception thrown within the catch, y, masks the exception thrown in foo's try block. Then when the try-with-resources block is exited the close method is called and the exception thrown on close gets added onto the y exception that is in-flight. So your printlns show y, then iterate through the suppressed exceptions attached to y.
In the second example, c is what's thrown from the go method (it's the same masking behavior described above). The IOException in the go method try block got thrown, the close method was called on the way out, causing the exception on close to get added to the IOException as a suppressed exception, then the IOException gets masked by c. Because a got masked, and the suppressed exception was attached to a, we lose the suppressed exception too. The c exception thrown on close has no suppressed exceptions associated with it because it was generated after the try-with-resources block was exited.
From the Oracle documentation http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html:
If an exception is thrown from the try block and one or more exceptions are thrown from the try-with-resources statement, then those exceptions thrown from the try-with-resources statement are suppressed. You can retrieve these suppressed exceptions by calling the Throwable.getSuppressed method from the exception thrown by the try block.
So as expected the first example gives the output:
java.lang.RuntimeException: y
suppressed java.lang.RuntimeException: a
In the second code snippet also there is a case of Exception Suppression. To validate that I have modified your function as:
void go() {
try (Animal a = new Animal()) {
throw new IOException();
} catch (Exception e) {
for (Throwable t : e.getSuppressed()) {
System.err.println("suppressed " + t);
}
throw new RuntimeException("c");
}
}
Then the output will be:
suppressed java.lang.RuntimeException: a
java.lang.RuntimeException: c

Is there any way to don't use 'instance of' with objects that I can't extend?

I've a custom exception with few attributes that inherits from Exception class.
Depending on instance of Exception I would like to return a code.
Code:
public int manageException(Exception exception) {
int code = 0;
if (exception instanceof MyCustomException) {
code = ((MyCustomException) exception).getCode();
} else if (exception instanceof NestedRuntimeException) {
code = 444;
} else if (exception instanceof HibernateException) {
code = 555;
} else {
code = 666;
}
return code;
}
If
You need to handle these exceptions in multiple locations, and
You don't want multiple catch blocks (one for each exception type) in each location
...then instanceof is about as clean as you're likely to get in Java 7.
Having said that, though, you could do this:
public void manageException(Runnable r) {
try {
r.run();
}
catch (NestedRuntimeException nre) {
throw new MyCustomException(444, nre);
}
catch (HibernateException he) {
throw new MyCustomException(555, he);
}
catch (Exception e) {
throw new MyCustomException(666, e);
}
}
...and then everywhere you need it:
try {
this.manageException(new Runnable() {
#Override
public void run() {
// Do something
}
});
}
catch (MyCustomException mce) {
int code = mce.getCode();
}
...but it's not buying you much and it's really ugly. :-)
In Java 8, it's a lot cleaner. manageException is the same, but the calls are just:
try {
this.manageException(() => {
// Do something here
});
}
catch (MyCustomException mce) {
int code = mce.getCode();
}
For me, the Java 8 version nearly starts winning over instanceof. The Java 7 version, not so much.
(Why Runnable in the above? Because the JDK authors decided not to define a new standard functional interface that accepts no arguments and has no return value; more in this question. They generalized the concept of Runnable instead. If the semantics bother you (they would me), you can define your own.)
You can use overloading like this:
public int manageException(MyCustomException e) {
return e.getCode();
}
public int manageException(NestedRuntimeException e) {
return 444;
}
public int manageException(HibernateExceptionexception e) {
return 555;
}
public int manageException(Exception e) {
return 666;
}
Edit after comment from #T.J. Crowder:
Keep in mind that you will still need multiple catch blocks in order to call the correct method. The overload is based on the compile-time type of the exception. Simply doing catch (Exception e) { int code = this.manageException(ex); } will always return 666.
If you want to map the type of exception to different error codes, you could use a map:
Map<Class<? extends Exception>, Integer> map = new HashMap<> ();
map.put (Exception.class, 5);
map.put (NullPointerException.class, 42);
try {
throw null; //throws NPE
} catch (Exception e) {
System.out.println (map.get (e.getClass ())); //output is 42
}
I think this would be easy expendable, as you could read the mapping from a config file instead of hard coding it, so you could add other exception and error codes without making changes to your code.
You have to test the return value of map.get() for null, as it could be an Exception you didn't specify before so there is no Integer mapped to it.
Attention: As mentioned in the first comment, this would only work if you want to have an exact mapping of Classes to error codes. If Subclasses of an exception should have the same error code as their super class, this solution won't work without modification.

Call constructor from constructor and catch exceptions

I have a constructor which calls another constructor in the same class. The problem is I want to catch Exceptions and throw them onwards to the method that called the first constructor. Yet Java doesn't allow this as the constructor call must be the first statement in the constructor.
public Config(String fn) throws IOException, ExcFormattingError {
theFile = fn;
try { cfRead(); }
catch(FileNotFoundException e) {
//create a new config with defaults.
theConfig = defaultConfig();
create();
} catch (IOException e) {
throw new IOException(e);
} catch (ExcFormattingError e) {
throw new ExcFormattingError();
}
fixMissing(theConfig);
}
public Config() throws IOException, ExcFormattingError {
try {
//Line below is in error...
this("accountmgr.cfg");
} catch (IOException e) {
throw new IOException(e);
} catch (ExcFormattingError e) {
throw new ExcFormattingError();
}
}
If someone could explain how I could do this that would be good. A bonus would be knowing why the language has to behave this way, because that is always interesting.
You don't need those try-catch block inside the constructor (in fact, you can't write it there, as you already figured out). So, change your constructor to:
public Config() throws IOException, ExcFormattingError {
this("accountmgr.cfg");
}
In fact the catch block in your constructor was hardly doing anything productive. It was just re-creating an instance of the same exception, and throwing it. That is really not needed given the fact that, if the exception is thrown, it will automatically propagated to the caller code, where you can handle the exception.
public void someMethod() {
Config config = null;
try {
config = new Config();
} catch (IOException e) {
// handle it
} catch (ExcFormattingError e) {
// handle it
}
}
Having said that, it is rarely a good idea to throw a checked exception from the constructor, even worse handling them in the caller code.
If the exception is thrown, and you handle it in the calling method. Then you are simply ignoring the fact that your instance is not completely initialized. Proceeding with that instance further will result in some unexpected behaviour. So, you should avoid it really.

exception.getMessage() output with class name

I'm trying to fix an issue, in my application I have this code
try {
object1.method1();
} catch(Exception ex) {
JOptionPane.showMessageDialog(nulll, "Error: "+ex.getMessage());
}
and the object1 would do something like that:
public void method1() {
//some code...
throw new RuntimeException("Cannot move file");
}
I get a messsage in my option pane like this:
Error: java.lang.RuntimeException: Cannot move file
but I used getMessage and not toString method, so the name of the class shouldn´t appear, right?
What I am doing wrong?
I already tryied with a lot of exceptions, even Exception itself. I'm looking to solve this no without the need to implement my own Exception subclass
PROBLEM SOLVED - thank you all!
The try and catch were actually being called in get() method from SwingWorker which constructs an ExecutionException with my exception thrown from doInBackground()
I fixed doing this:
#Override
protected void done() {
try {
Object u = (Object) get();
//do whatever u want
} catch(ExecutionException ex) {
JOptionPane.showMessageDialog(null, "Error: "+ex.getCause().getMessage());
} catch(Exception ex) {
JOptionPane.showMessageDialog(null, "Error: "+ex.getMessage());
}
}
I think you are wrapping your exception in another exception (which isn't in your code above). If you try out this code:
public static void main(String[] args) {
try {
throw new RuntimeException("Cannot move file");
} catch (Exception ex) {
JOptionPane.showMessageDialog(null, "Error: " + ex.getMessage());
}
}
...you will see a popup that says exactly what you want.
However, to solve your problem (the wrapped exception) you need get to the "root" exception with the "correct" message. To do this you need to create a own recursive method getRootCause:
public static void main(String[] args) {
try {
throw new Exception(new RuntimeException("Cannot move file"));
} catch (Exception ex) {
JOptionPane.showMessageDialog(null,
"Error: " + getRootCause(ex).getMessage());
}
}
public static Throwable getRootCause(Throwable throwable) {
if (throwable.getCause() != null)
return getRootCause(throwable.getCause());
return throwable;
}
Note: Unwrapping exceptions like this however, sort of breaks the abstractions. I encourage you to find out why the exception is wrapped and ask yourself if it makes sense.
My guess is that you've got something in method1 which wraps one exception in another, and uses the toString() of the nested exception as the message of the wrapper. I suggest you take a copy of your project, and remove as much as you can while keeping the problem, until you've got a short but complete program which demonstrates it - at which point either it'll be clear what's going on, or we'll be in a better position to help fix it.
Here's a short but complete program which demonstrates RuntimeException.getMessage() behaving correctly:
public class Test {
public static void main(String[] args) {
try {
failingMethod();
} catch (Exception e) {
System.out.println("Error: " + e.getMessage());
}
}
private static void failingMethod() {
throw new RuntimeException("Just the message");
}
}
Output:
Error: Just the message

Categories

Resources