I am trying to throw a custom exception
class NumberFormatException extends Exception
{
public NumberFormatException() {}
//Constructor that accepts a message
public NumberFormatException(String message)
{
super(message);
}
}
Later, I am throwing this exception using
throw new NumberFormatException("Exception found");
and later on catching it using
catch(NumberFormatException e)
{
System.out.println(e);
}
It prints something like
NumberFormatException: Exception found
Is it possible to print something like:
java.lang.NumberFormatException: Exception found
The constraint is the catch code can't be modified i.e
catch(NumberFormatException e)
{
System.out.println(e);
}
You are trying to get Canonical name of exception class and here is how you can get it:
catch(NumberFormatException e)
{
System.out.println(e.getClass().getCanonicalName());
}
Refer javadoc for more : getCanonicalName
Override toString In your NumberFormatException class :
class MyException extends Exception{
String message;
public MyException(String string) {
this.message = string;
}
#Override
public String toString() {
String s = getClass().getCanonicalName();
String message = this.message;
return (message != null) ? (s + ": " + message) : s;
}
}
Source : Throwable
Here is a full code testing the method :
package first;
class MyException extends Exception{
String message;
public MyException(String string) {
this.message = string;
}
#Override
public String toString() {
String s = getClass().getCanonicalName();
String message = this.message;
return (message != null) ? (s + ": " + message) : s;
}
}
public class TestingMyException{
public static void main(String[] args) {
try{
throw new MyException("This works !");
}catch(MyException e){
System.out.println(e);
}
}
}
Output
first.MyException: This works !
Since my class is defined in the package named first of my root, the result prints first.MyException.
So you also have to check if your class is not defined in the default package. Otherwise, you'll not get anything but :
MyException: This works !
Related
Instead of the try{}catch(Exception e){} method, is there a way to just state a custom message that replaces the exception message when exceptions like InputMismatchException, NoSuchElementException etc. occurs anywhere on the program?
EDIT: I want another method because if I use try{}catch(Exception e){} method than I will have to do it everywhere and the code also becomes longer.
For example:
public static String genderOutput()
{
try
{
System.out.print("\nMale - 1 \nFemale - 2 \n\nEnter either 1 or 2: ");
int genderInput = userInput.nextInt();
if(genderInput == 1)
{
String userGender = "Mr.";
return userGender;
}
else if(genderInput == 2)
{
String userGender = "Mrs.";
return userGender;
}
else
{
String userGender = " ";
return userGender;
}
}
catch (Exception e)
{
return null;
}
}
I have this function, now if there were multiple functions in a class like this then I would have to have the try{}catch(Exception e){} method everywhere. Wouldn't it be more efficient if you can just replace the exception message with your own and when such exception occurs which has a custom message stated to them then it would just throw out the custom message instead. This way, the code will be shorter as well.
SOLUTION TO MY PROBLEM:
public class Test
{
public static Scanner userInput = new Scanner(System.in);
public static String titleName = "TheRivalsRage";
public static String exitLevelMessage = "Program exited!";
public static String errorMessageTitle = "\n[Error] ";
public static String intInputMismatchException = "Please enter an Integer Value!";
public static String intNoSuchElementException = "Please enter either '1' or '2' without the quotes!";
public static String lineNoSuchElementException = "Please enter something!";
public static String bothIllegalStateException = "Scanner closed unexpectedly!";
public static void main(String[] args)
throws Exception
{
String usernameOutput;
String userGender;
try
{
System.out.print("Enter your username: ");
usernameOutput = userInput.nextLine();
userGender = genderOutput();
userInput.close();
}
catch(IllegalStateException e)
{
throw new IllegalStateException(errorMessageTitle + bothIllegalStateException);
}
if(userGender == null)
{
noSuchElementException();
}
else
{
System.out.println("\nWelcome " + userGender + " " + usernameOutput + " to " + titleName);
}
}
public static String genderOutput()
{
String userGender;
int genderInput;
System.out.print("\nMale - 1 \nFemale - 2 \n\nEnter either 1 or 2: ");
try
{
genderInput = userInput.nextInt();
}
catch(InputMismatchException e)
{
genderInput = 0;
inputMismatchException();
}
if(genderInput == 1)
{
userGender = "Mr.";
}
else if(genderInput == 2)
{
userGender = "Mrs.";
}
else
{
userGender = null;
}
return userGender;
}
public static void inputMismatchException()
throws InputMismatchException
{
throw new InputMismatchException(errorMessageTitle + intInputMismatchException);
}
public static void noSuchElementException()
throws NoSuchElementException
{
throw new NoSuchElementException(errorMessageTitle + intNoSuchElementException);
}
}
don't handle exception in each and every method just use throws Exception after method signature and handle it at end where the methods are being called.
and there in catch block you can throw your custom exception.
void method1() throws Exception{
//
}
void method2() throws Exception{
//
}
void finalmethod(){
try{
method1();
method2();
}catch(InputMismatchException e){
throw customExcpetion("custommessage1");
}catch(Exception e){
throw customExcpetion("custommessage2");
}
}
You need a try/catch.
However, you do not need to catch all exceptions separately, because the exceptions that you mention are all subclasses of RuntimeException. Hence, it is sufficient to make a single try/catch in your main to intercept RuntimeException, and print the replacement message:
public static void main(String[] args) {
try {
... // Actual code
} catch (RuntimeException ex) {
System.err.println("A runtime error has occurred.");
}
}
You can try Aspectj or Spring aop by creating around advice. You can replace message by catching exception inside advice and rethrow.
Check http://howtodoinjava.com/spring/spring-aop/aspectj-around-advice-example/
To know about how to use spring aop for anound advice
Java doesn't provide this feature out of the box but nobody prevents you to create a class that composes a Scanner object and that decorates methods that you are using as nextInt().
Inside the decorated method, invoke nextInt(), catch the exception that it may throw and handle it by returning null as in your question.
If it makes sense, you could even provide a nextInt() method with a default value as parameter if the input fails.
public class MyCustomScanner{
private Scanner scanner;
...
public Integer nextInt(){
try{
return scanner.nextInt()
}
catch(InputMismatchException e){
myStateObj.setErrorMessage("....");
return null;
}
}
public Integer nextInt(Integer defaultValue){
try{
return scanner.nextInt()
}
catch(InputMismatchException e){
myStateObj.setErrorMessage("....");
return defaultValue;
}
}
}
Now you can use the class in this way :
MyCustomScanner scanner = new MyCustomScanner();
Integer intValue = scanner.nextInt();
Integer otherIntValue = scanner.nextInt(Integer.valueOf(4));
I define a custom exception like so :
package source.exception;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ValidationException extends Exception
{
private static final Logger logger = LoggerFactory.getLogger("source.exception.ValidationException");
public ValidationException(String message)
{
super(message);
ValidationException e = new ValidationException();
logger.error("Exception : {}" , e);
}
}
In the main program I use this exception like so :
public void readFile(String path) throws ValidationException
{
logger.debug("Input file path = {}" , path);
try
{
if(validatePath(path))
{
mathExpressionReader = new BufferedReader(new FileReader(path));
}
else
{
throw new ValidationException("Your file dose not exist!");
}
}
catch(Exception ex)
{
logger.error("Exception {} has occurred" , ex);
}
}
Now I don't know how to print stack trace when validatePath fail(means if statement become false) .Can anyone help me to print stack trace in custom exception?
Why not just using e.printStackTrace()?
public class ValidationException extends Exception
{
public ValidationException(String message)
{
super(message);
}
}
public void readFile(String path) throws ValidationException
{
logger.debug("Input file path = {}" , path);
try
{
if(validatePath(path))
{
mathExpressionReader = new BufferedReader(new FileReader(path));
}
else
{
throw new ValidationException("Your file dose not exist!");
}
} catch (ValidationException e) {
// This will print the stack trace.
e.printStackTrace();
}
}
I'm sure this is a very stupid question, but still I would like to know, is it possible to cast the global variable cause dynamically, in other words without using the instanceof operator ?
The reason for this question is, I feel the instanceof operator is not doing anything great here, it's just casting the cause statically, but in either case it's creating a new IOException(cause)
Because the cause is of type Object, I had to type cast it to either String or Throwable.
private Object cause; // global variable
//...
if (failed)
throw cause instanceof String ? new IOException((String) cause) : new IOException((Throwable) cause);
Below is the actual code snippet where the two overridden methods will be called asynchronously.
public class Command implements ResponseListener {
private Object cause;
// ...
#Override
public void messageReceived(String message, String status) {
// ...
if (!status.equals(MyConstants.COMPLD_MSG)) {
this.cause = status + " received for " + command.split(":")[0] + message;
this.failed = true;
}
doNotify();
}
#Override
public void exceptionCaught(Throwable cause) {
this.cause = cause;
this.failed = true;
doNotify();
}
public void waitForResponse(int cmdTimeout) throws IOException, InterruptedException {
// ...
if (failed)
throw cause instanceof String ? new IOException((String) cause) : new IOException((Throwable) cause);
}
}
Why not having always a Throwable for your cause variable ? Throwable seems more adapted to express a failure than a String. Plus it avoids you to use the "ugly" operator instanceof.
public class Command implements ResponseListener {
private Throwable cause;
// ...
#Override
public void messageReceived(String message, String status) {
// ...
if (!status.equals(MyConstants.COMPLD_MSG)) {
this.cause = new Throwable(status + " received for " + command.split(":")[0] + message);
this.failed = true;
}
doNotify();
}
#Override
public void exceptionCaught(Throwable cause) {
this.cause = cause;
this.failed = true;
doNotify();
}
public void waitForResponse(int cmdTimeout) throws IOException, InterruptedException {
// ...
if (failed)
throw new IOException(cause);
}
}
Update after discussion below:
public class Command implements ResponseListener {
private String cause;
// ...
#Override
public void messageReceived(String message, String status) {
// ...
if (!status.equals(MyConstants.COMPLD_MSG)) {
this.cause = status + " received for " + command.split(":")[0] + message;
this.failed = true;
}
doNotify();
}
#Override
public void exceptionCaught(Throwable cause) {
if(cause.getMessage().isEmpty()) {
this.cause = cause.toString();
}
else {
this.cause = cause.getMessage();
}
this.failed = true;
doNotify();
}
public void waitForResponse(int cmdTimeout) throws IOException, InterruptedException {
// ...
if (failed)
throw new IOException(cause);
}
}
As there is no common superclass of String and Throwable that would be acceptable as parameter to IOException, you have to cast it to one or the other, and in order to determine what to cast it to, you have to use instanceof.
Class.cast and Class.isAssignableFrom methods may be used as dynamic counterparts of cast and instanceof operators respectively.
For some reason I am missing part of the stack trace, the actual root of the exception.
public void method1(){
try{
method2();
}
catch(SearchException e){
logger.error("Search error", e.getMessage(), e);
}
}
private void method2(){
try{
//Logic which potentially can throw exception
....
....
}
catch(Exception e){
throw new SearchException("Error during execution Module A", e);
}
}
public class SearchException extends Exception{
public SearchException(String message, Throwable cause) {
super(message, cause);
}
}
Anyone knows a reason why I am missing part of stacktrace where fist place exception happened? Could you suggest a correct way of handling/logging exceptions?
super(message, cause);
The message will be the detailMessage of Throwable class. And it will be used in toString method and source cause(Exception) will be ignored.
358 public String toString() {
359 String s = getClass().getName();// class Name
360 String message = getLocalizedMessage();// detailMessage
361 return (message != null) ? (s + ": " + message) : s;
362 }
You may override the toString method in custom Exception class.
class SearchException extends Exception{
String str=null;
public SearchException(String str,Throwable th){
super( th);
this.str=str;
}
public String toString(){
return super.toString() +" - "+ str;
}
}
This customized form will print -
Search error
-----java.lang.NullPointerException-------SearchException: java.lang.NullPointerException - Error during execution Module A
The exception is never shown .
extended Exception class and override the method toString.and then called it.according to the condition it should display hahah , but it doesn't show anything..no errors either.
class Excp extends Exception {
public String toString() {
return "hahah";
}
}
public class exc {
boolean a = false;
void hey() throws Excp {
if (a)
throw new Excp();
}
public static void main(String... s) {
try {
new exc().hey();
} catch (Excp e) {
System.out.println(e);
}
}
}
Your condition
if(a)
will return false as you have intiialized a=false. Hence the if block will not execute the statement
throw new Excp();
Here
{
if(a)
throw new Excp();
}
A is false. Never goes in side the condition, because you haven't making true while initializing the object.
Try
try
{
Excp exc = new Excp();
exc.a= true;
exc.hey();
}
Side notes:
1)Please follow naming conventions.
2)Provide encapsulation.
3)Format your code always.
I think that you want to have a custom exception with your own error message, If so you can do like this
class MyException extends Exception{
MyException(String errorMsg){
super(errorMsg);
}
}
class Test{
public static void main(String[] args){
if(someCondition)
throw new MyException("My error message");
}
}