With a code like this
public static void main(String[] args) {
Exception one = new Exception("my cause");
System.out.println("A) " + one.getMessage());
System.out.println();
Exception two = new Exception(one);
System.out.println("B) " + two.getMessage());
System.out.println("C) " + two.getCause().getMessage());
System.out.println();
Exception three = new Exception("my message", one);
System.out.println("D) " + three.getMessage());
System.out.println("E) " + three.getCause().getMessage());
System.out.println();
Exception fourth = new Exception(null, one);
System.out.println("F) " + fourth.getMessage());
System.out.println("G) " + fourth.getCause().getMessage());
}
The output is this one
A) my cause
B) java.lang.Exception: my cause
C) my cause
D) my message
E) my cause
F) null
G) my cause
See the difference between B and F
In both cases I did NOT provided a message, but the difference is that in the B case the null value is not forced.
It seems that for the B case, when a message is not specified, the getMessage() method provides the format
className: cause.getMessage()
But I would except to have a null value (as is for the F case).
Is there a way to get null value (like F) if I call the getMessage on an Exception that has been created providing only the cause and not the message?
Take a look at Exception's JavaDoc. For the constructor that takes only a Throwable:
Constructs a new exception with the specified cause and a detail message of (cause==null ? null : cause.toString()) (which typically contains the class and detail message of cause). This constructor is useful for exceptions that are little more than wrappers for other throwables (for example, PrivilegedActionException).
So, in your B case, since the cause is not null, you get the value of cause.toString() as the container exception's message.
If that constructor was used to create the exception, then by the time you catch the exception, it's too late - it already has a detail message as specified above. You can't get the "null" as the detail message is not null. You can compare it to the cause's toString() and deduce that it should have been null, but that's a kludge and theoretically, the cause's message could change over time and be different at the time of the catch.
Basing on #RealSkeptic reply I created a method like this
public static String getMessageOrNull(Throwable t) {
String message = t.getMessage();
if (t.getCause() != null && message.equals(t.getCause().toString())) {
message = null;
}
return message;
}
It may not be the best approach but for my case works just fine.
You could simply build it the same way, hiding it in a static method :
public static Exception getException(Throwable cause){
return new Exception(null, cause);
}
Or you define your own class that will use the Exception(String, Throwable) constructor like
public MyExceptoin extends Exception{
public MyException(Throwable cause){
super(null, cause);
}
}
This would be simpler to use later.
Related
Recently I saw following piece of code on GitHub:
private static String safeToString(Object obj) {
if (obj == null) return null;
try {
return obj.toString();
} catch (Throwable t) {
return "Error occured";
}
}
I've never placed toString() method invocations inside the try-catch blocks. But now when I think about it, it might make sense. For example someone could overwrite toString() method in it's class that might throw a runtime exception, like NullPointerException. So we can try to catch Exception. But why Throwable? Do you think it makes any sense?
There is almost never a good reason to do this. The contract of toString() does not say it’s permissible to throw an exception from that method. Any code which throws an exception is broken code, and such an exception needs to be exposed and fixed, not suppressed.
In the case where you are converting some “bad” object from a library which is out of your control to a String, it might be appropriate to write catch (RuntimeExcepton e), but such a catch should be accompanied by comments which describe in detail why it is necessary, because under normal circumstances, it is not needed.
Rogue exception-throwing toString methods aside, note that Java already has at least two “safe” ways to convert a possibly null value to a String:
Objects.toString(obj, null)
String.valueOf(obj)
…so I would question whether the safeToString method should exist at all.
There are rare cases where you might want to catch an Error like this. In general it's a bad idea however, in this case it might make sense as this is generally for logging/debugging purposes and not used directly by the application.
I would prefer something more informative such as
private static String safeToString(Object obj) {
if (obj == null) return null;
try {
return obj.toString();
} catch (Throwable t) {
return obj.getClass() + ".toString() threw " + t;
}
}
e.g.
class Element {
Object data;
Element e;
public String toString() {
return data + (e == null ? "" : e.toString());
}
}
Element e = new Element();
e.data = "hi";
e.e = e; // oops
System.out.println("e: " + safeToString(e)); // doesn't kill the thread or JVM.
Throwable is the parent class of Exception and Error.
It is normally a bad idea to try and catch Error, as it is designed to not be caught.
Catching Throwable is just the overachieved and counterproductive version of catching Exception. Nonetheless, if for some reason you created another kind of Throwable you want to catch along with an Exception, that could be a way to do that in a single try/catch block. Not that it would be a clean way to do so, but it would work.
EDIT for the TL;DR : in most cases, catch Exception instead of Throwable.
It is incorrect to catch any Throwable and then continue execution since it includes Error, which is meant to be fatal:
From the Javadocs:
An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch. Most such errors are abnormal conditions. The ThreadDeath error, though a "normal" condition, is also a subclass of Error because most applications should not try to catch it.
That is, some Errors can be recovered (e.g. LinkageError), but others not so much.
But catching Exception might be a valid use-case for example in logging code where you don't want the execution to break simply because a call to toString() fails:
private static String safeToString(Object obj) {
try {
return obj == null ? "null" : obj.toString();
} catch (Exception e) {
return "<exception: " + e + ">";
}
}
I am displaying countries and it's codes using Locale.class.
I just want to know How is the exception handled in the follwing code
public Locale(String language, String country, String variant) {
if (language== null || country == null || variant == null) {
throw new NullPointerException();
}
baseLocale = BaseLocale.getInstance(convertOldISOCodes(language), "", country, variant);
localeExtensions = getCompatibilityExtensions(language, "", country, variant);
}
as I'm not catching it in my class
String[] locales = Locale.getISOCountries();
for (String countryCode : locales) {
Locale obj = new Locale("", countryCode); //NullPointerException - thrown if either argument is null.
System.out.println("Country Code = " + obj.getCountry()
+ ", Country Name : " + obj.getDisplayCountry());
}
As I know the method has to use throws to throw any new Thowable object and the newly throwned object must be handled in the implemented class.
I'm a Newbie with exception handling in java.
Per the NullPointerException Javadoc, it extends RuntimeException. And per the RuntimeException Javadoc,
RuntimeException and its subclasses are unchecked exceptions. Unchecked exceptions do not need to be declared in a method or constructor's throws clause if they can be thrown by the execution of the method or constructor and propagate outside the method or constructor boundary.
In your example, if you trigger that NullPointerException your JVM will terminate and display a stack trace.
Have toString standard method inside my class that overrides Object ones.
Is it good practice to use try catch in this method?
#Override
public String toString() {
try {
return
"number='" + product.getProductNumber() +
", locale=" + locale;
} catch (ProductException e) {
return super.toString();
}
}
No, this is not normal practice. Exceptions should be used to handle exceptional situations, not the regular code flow.
Your code uses try/catch to detect situations that could be handled without introducing exceptions. It is roughly equivalent to the following method:
#Override
public String toString() {
if (product.checkProductNumber()) {
return "number='" + product.getProductNumber() +
", locale=" + locale;
} else {
return super.toString();
}
}
The imaginary checkProductNumber method returns true when getProductNumber call would not throw ProductException, and false otherwise. Making a method like checkProductNumber and using it instead of catching the exception is a better way of coding methods where exceptions are caught during the normal program flow.
Using Try/Catch in toString in not a normat practice but there is no restriction to use try/catch in toString method().
but if you want to remove try/catch in your code then you must have a knowledge that who throw this ProductException exception and what are the condition in which this exception is thrown.
If this is checked exception then in that case you can create temp method with boolean option to check whether this operation will run normally or throw an exception. As shown in #dasblinkenlight answer.
Note: best practice says that toString() method is always overridden in those classess who contains some data and in those type of classes getter/setter is only used for getting and setting values so there is no chance of exception.
If you want to do some opertion on data then try to do that outside of the this class. Use these type of classes to only contains data and don't perform operation inside the class(except small operation only if extremly required)
I don't see any obvious reason for not doing it like this. However your current proposal will loose the locale info if a ProductException is thrown. Unless you only want this OR the super.toString(), maybe you should do something like this:
#Override
public String toString() {
String number = null;
try {
number = product.getProductNumber();
} catch (ProductException e) {
number = "unknown: " + e.getMessage(); // or something like this
}
// here you may or may not include super.toString()
return super.toString() + ", number=" + number + ", locale=" + locale;
}
I haven't seen the usage of try-catch in toString. But if you are using some method which can throw the exception then I dont see any issue in using try-catch inside of toString
Yes there is nothing wrong with this.If you know that any exception will occur in toString() then you can use try-catch{ } in it.
If The method product.getProductNumber() may throw the ProductException it is the right way.
I have 2 classes, one that implements a double lookup( int i);
and one where I use that lookup(int i) in solving a question, or in this case printing the lookup values. This case is for an array.
So I read the exception documentation or google/textbook and come with the following code:
public double lookup(int i) throws Exception
{
if( i > numItems)
throw new Exception("out of bounds");
return items[i];
}
and take it over to my class and try to print my set, where set is a name of the
object type I define in the class above.
public void print()
{
for (int i = 0; i < set.size() - 1; i++)
{
System.out.print(set.lookup(i) + ",");
}
System.out.print(set.lookup(set.size()));
}
I'm using two print()'s to avoid the last "," in the print, but am getting an
unhandled exception Exception (my exception's name was Exception)
I think I have to catch my exception in my print() but cannot find the correct formatting online. Do I have to write
catch exception Exception? because that gives me a syntax error saying invalid type on catch.
Sources like
http://docs.oracle.com/javase/tutorial/essential/exceptions/
are of little help to me, I'm can't seem to grasp what the text is telling me. I'm also having trouble finding sources with multiple examples where I can actually understand the coding in the examples.
so could anybody give me a source/example for the above catch phrase and perhaps a decent source of examples for new Java programmers? my book is horrendous and I cannot seem to find an understandable example for the above catch phrase online.
I wouldn't throw Exception ever.
In your case, IndexOutOfBoundException or InvalidArgumentException would eb a better choice. As these are not checked Exceptions, you don't need to catch them.
public double lookup(int i) {
if(i >= numItems) // assuming numItems is not items.length
throw new IndexOutOfBoundException("out of bounds " + i + " >= " + numItems);
return items[i];
}
Note: the check should be >=
Your print() method will now compile unchanged.
What is Exception?
Exceptions are for exceptional conditions. Conditions that normally do not occur. Take an example you went to withdraw money and your account has 100 balance and you asked for 200 then ATM should tell you that you have insufficient balance.
Types of Exceptions
Checked Exception
These are conditions where application wants to recover from it. Like example given above application will give you error and will continue working.
Error
This is an exceptional condition which is external to application. We say OutOfMemoryError when there isn't enough memory available and application can not recover from it.
Runtime Exception /Unchecked Exception
These exceptions are applications exception but in this case application can not recover from it. E.g NullpointerException if value is null and you try do something nasty with it.
so of above three only checked exceptions need to be cached.
How to throw and Catch Checked Exception
Exception or any subclass of Exception is a checked exception. A checked exception can be thrown using throw clause. Once you throw an exception it becomes mandatory for you to include that in method declaration using throws clause.
So whoever want to use this method will now have to handle that exception. Handling exception means invoking alternative flows. Like in our case we displayed text to user "Error Invalid account number."
Calling function can also choose to propagate exceptions by adding throws clause for those exceptions which are thrown by method it is calling.
Generate:
public static double withdraw(int i) throws Exception {
if (i <= 0)// Out of bounds
throw new Exception("Invalid Account Number");
return 0.0;// something;
}
Handle:
try {
withdraw(0);
} catch (Exception e) {
// do something with exception here.
// Log the exception
System.out.println("Error Invalid account number.");
}
Propagate:
public static double callWithdraw(int i) throws Exception {//Propagate exceptions
return withdraw(i);
}
Try this
try
{
print(); //print() needs to throw the same exception
} catch(Exception e)
{
//handle exception
System.err.println(e.getMessage()+"\n\n"+e.printStackTrace());
}
//finally {
// cleanup here if you like
// }
or this
public void print()
{
for (int i = 0; i < set.size() - 1; i++)
{
try
{
System.out.print(set.lookup(i) + ",");
} catch(Exception e)
{
//handle it here
}
}
System.out.print(set.lookup(set.size()));
}
Do note that using "throws" is kind of a easy way out; it's a cheap delegation that sometimes makes coding easier... if you can, you should try to always use try/catch instead of throws.
Just be aware that whenever you use something with "throws" eventually you will have to put that in a try/catch block and deal with it properly.
Generally to denote improper arguments passed into your method, use IllegalArgumentException which is a RuntimeException and should not be caught.
In this specific case you don't have to write any extra code, the ArrayIndexOutOfBoundsException should take care of improper array access.
Thrown to indicate that an array has been accessed with an illegal
index. The index is either negative or greater than or equal to the
size of the array.
I am debugging my application, I have added exception.getMessage() in logger, but exception.getMessage() prints Null, but , when I debug I could see my Exception String in exception object's detailed message, how can I get the exception message that is coming as detailed message? Note - getMessage returns Null.
P.S - I am not using PrintStackTrace or stacktraceElement, my logger should return the string from exception.getmessage(), that is the requirement.
From comment:
DBException dbExe = new DBException(sqlExe);
DBException objDbEx = (DBException) ExceptionUtil.populateSuperException(dbExe, strTraceMesg, ConstantsIF.SEVERE_LEVEL, false, null, null, null);
throw objDbEx;
public static SuperException populateSuperException (SuperException exSuperException, String strTraceMsg, char chTraceLevel, ) {
if (strTraceMsg != null) {
switch (chTraceLevel) {
case Con.IN:
case Con.S:
//log
}
}
return exSuperException;
}
You can print out the full stack trace:
exception.printStackTrace();
Try:
switch (chTraceLevel) {
case Con.IN:
case Con.S:
String msg = exSuperException.getCause().getMessage();
// LOG msg
}
That is pretty strange. The message that you see with debugging is usually created through Throwable#toString and that calls getLocalizedMessage() internally.
So if the exception does have a message, then it should be returned through getMessage() and be part of the toString() result.
An exception/throwable does not need to have a detailed message. Please double check, if you've created your exceptions with a message.
After making your code readable: your DBException is created without a message, so dbExe.getMessage() will return null. Either look the the cause or add a message while creating:
DBException dbExe = new DBException(sqlExe.toString(), sqlExe);// just an example
You are creating your exception object without any message (you're only specifying the chained exception):
DBException dbExe = new DBException(sqlExe);
hence calling dbExe.getMessage() may (correctly) return null (with the details depending on what your constructor does in this situation). The reason you can see a message in the stacktrace, incidentally, is because the generation of the stacktrace recurses to the underlying exception, and sqlExe.getMessage() will be what you're seeing.
The solution is simply to provide a message as well as the underlying exception when constructing your exception. The general wisdom is that this should reflect the level at which the exception is thrown, so perhaps something like the following:
DBException dbExe = new DBException("Unable to persist widgets", sqlExe);
If your unspecified "requirement about the existing code flow" means that you need the actual database exception to be the message in dbExe, you could construct this like the following:
DBException dbExe = new DBException(sqlExe.getMessage(), sqlExe);
though on the whole that duplication of the message isn't very nice, and the former option is the more "correct" one.
From the discussion in the comments, it is my conclusion that the root cause of your problem is in the implementation of the DBException constructor or its hierarchy. For a valid reason or not, I think it's not calling the exception class hierarchy (e.g. super(reason);) and therefore, you are not getting the expected behaviour from the call to dbException.getMessage(). Note that a call to new Exception(anotherException) will always populate the field backing the getMessage() call in the base Throwable class through this call chain: (only relevant bits shown)
public Throwable(Throwable cause) {
...
detailMessage = (cause==null ? null : cause.toString());
...
}
public String toString() {
...
String message = getLocalizedMessage();
...
}
public String getLocalizedMessage() {
return getMessage();
}
Check the implementation of DBException as the root cause of the problem discussed.