Exceptions in Swing from helper classes - java

I am working on a homework assignment to convert this Java Tutorial of the Knock Knock application to a Swing GUI application and use multithreading.
I have helper classes that are throwing Exceptions. These classes do not extend JFrame and I can't create new JOptionPane to show the exception. How would you show that Exception to the user?
For example: I have a class that loads the jokes from two text files (one for the clues and one for the answers). If the text files cannot be found in the location I expect, I am throwing a NullPointerException. Because this is a helper class it is not extending JFrame. How would I relate that message to the user? Do I just reference the javax.swing.JOptionPane showMessageDialog method like I have it in my code below or I can have another proxy class that catches exceptions and shows them?
private final void getFilePath(ResponseFiles fileToGet) {
String packagePath = "/com/knockknock/message";
try {
if (fileToGet == ResponseFiles.CLUES)
file = new File(getClass().getResource(String.format("%s/clues.txt", packagePath)).getPath());
else if (fileToGet == ResponseFiles.ANSWERS)
file = new File(getClass().getResource(String.format("%s/answers.txt", packagePath)).getPath());
} catch (NullPointerException e) {
javax.swing.JOptionPane.showMessageDialog(null, "Jokes Files Missing", "File Missing", JOptionPane.ERROR_MESSAGE);
}
What do you think?

Instead of using Swing components in business layer you can pass on the exceptions and handle it separately.
Have some custom Exception handler class where you can handle Runtime/Checked/Custom exceptions.
public class ExceptionHandler {
public void handleException(Exception exp) {
if (exp instanceof NullPointerException) {
javax.swing.JOptionPane.showMessageDialog(null,
"Jokes Files Missing", "File Missing",
JOptionPane.ERROR_MESSAGE);
} else if (exp instanceof IOException) {
javax.swing.JOptionPane.showMessageDialog(null, "Test", "Test",
JOptionPane.ERROR_MESSAGE);
}
//Handle other exceptions
}
}
Change your method like
private final void getFilePath(ResponseFiles fileToGet) {
String packagePath = "/com/knockknock/message";
if (fileToGet == ResponseFiles.CLUES)
file = new File(getClass().getResource(
String.format("%s/clues.txt", packagePath)).getPath());
else if (fileToGet == ResponseFiles.ANSWERS)
file = new File(getClass().getResource(
String.format("%s/answers.txt", packagePath)).getPath());
}
In your business layer where GUI interaction is done you can handle exception like this. In your case since it is Runtime exception no explicit throwing is required.
try {
getFilePath(ResponseFiles.CLUES);
} catch (Exception e) {
new ExceptionHandler().handleException(e);
}

Related

Android unreported exception IOException error

I am new to android apps development. Recently,Im writing an application which able to show public ip based on Ipify. So far, i already:
Download the required jar file and put inside libs folder
I also compile file within gradle
Then i import required class it to my class
How to use Ipify, according to its website:
import org.ipify.Ipify;
public class HelloIP {
public static void main(String[] args) throws IOException {
System.out.println(Ipify.getPublicIp());
}
}
I write the following method to be invoked from another class:
public static String getPublicIp() throws IOException{
String ip = Ipify.getPublicIp();
return ip;
}
Another Class
//Get wifi
getWifiName wifiInfo = new getWifiName();
String myIP = wifiInfo.getPublicIp();
However, i keep getting:
Error:(52, 43) error: unreported exception IOException; must be caught
or declared to be thrown
I tried to modify the code and use the following try and catch, but still got the same error.
public static String getPublicIp() throws IOException{
String myip = Ipify.getPublicIp();
try{
return myip;
}
catch (IOException e){
System.out.println("General I/O exception: " + e.getMessage());
e.printStackTrace();
}
}
Im not too good in catch and throw exception, and already spent the whole day for this.I dont have idea anymore to fix this error..T.T
public static String getPublicIp() {
try{
return Ipify.getPublicIp();
}catch (IOException e){
System.out.println("General I/O exception: " + e.getMessage());
e.printStackTrace();
}
return null;
}
In case it didn't help, clean project in your IDE. You may have some data cached and it might be a reason.
Your problem is in another class! As you have declared the method getPublicIp() to throw IOException that class is afraid of receiving the Exception and therefor requests catching it.
In Java you have two types of Exceptions. Checked and unchecked. Checked Exceptions must be caught.
In Java Exceptions are used for marking unexpected situations. For example parsing non-numeric String to a number (NumberFormatException) or calling a method on a null reference (NullPointerException). You can catch them in many ways.
Unchecked Exceptions are those which extend RunTimeException. They are used for marking unexpected states usually caused by user's input. They shouldn't cause harm and should be worked out with business logic. You don't have to catch them, but sometimes you should.
On the other hand there are Checked Exceptions which mark dangerous situations. For example the application being unable to open a file. As those situations are found dangerous, you must catch them.
try{
//some code
} catch (NumberFormatException e1) {
e.printStackTrace() //very important - handles the Exception but prints the information!
} catch (NullPointerException e2) {
e.printStackTrace();
}
or using the fact, that they all extend Exception:
try {
//somecode
} catch (Exception e) {
e.printStackTrace;
};
or since Java 7:
try {
//somecode
} catch (NullPointerException | NumberFormatException e) {
e.printStackTrace;
};

Throwing exceptions through components, good practice?

When a sub method throws an exception, would encapsulation in a dedicated "package" exception be considered good pratice ?
public String doStuff() throws UtilsException {
try {
throw new NullPointerException("test");
} catch (NullPointerException e) {
throw new UtilsException("something occured", e);
}
}
//use this exception for all classes of this package / component
public class UtilsException extends Exception {
private static final long serialVersionUID = 1L;
public UtilsException() {
super();
}
public UtilsException(String message, Throwable cause) {
super(message, cause);
}
public UtilsException(String message) {
super(message);
}
public UtilsException(Throwable cause) {
super(cause);
}
}
Could Optional.empty() be an alternative to avoid throwing/catching of a complex app?
public Optional<String> doStuff() throws UtilsException {
try {
return Optional.of("ok");
} catch (NullPointerException e) {
LOG.error("Something append... {}", e.getMessage());
return Optional.empty();
}
}
First, you should never catch a NullPointerException (or runtime exceptions in general) an return someting else like you are doing.
Ok, maybe there are a very few cases where you need to do that (like a buggy third party api).
Exceptions like those (NullPointer, ClassCast, IllegalArgument, ect) happen when your program has a bug and you should let
them bubble up and handle them in some high order component of your program.
That being said, (and there comes the infamous phrase) it depends...
Exceptions are "responsible" for informing errors,thus they need to be informative for the caller will use them to decide what to do. Consider the following:
public void readFile(String path) throws IOException {
// read file content
return content;
}
try {
return readFile("foo.txt");
} catch(FileNotFound e) {
// For this specific scenario not finding the file is not a problem
return "";
} catch(IOException e) {
// This we are not expecting to happen, if the file exists we should be
// able to read it, otherwise we should inform the user.
log.error(e);
display("We had a problem reading the file, Check the file permissions and try again");
}
As you can see in the example above, you won't want to wrap the IOException in another exception in this case
because you will remove the client's ability to decide what to do when an error happened.
Also, note that the IOException is a form of "wrap" since exceptions are objects too you can use inheritance
to generalize what kind of errors your method throws and then throw more specific errors so the caller can
decide what to do.
When to wrap.
There are cases when wrapping exceptions is a good practice and is the way to go.
For example, if you are creating a lib whose main functionality is to get weather information.
For the first version you kept it simple and used a third party api to get the values for the day.
The main method of your api looks like this.
public Weather getWeather(Date day) throws HTTPException {
return weather.get(day);
}
Your api is doing pretty well but you noticed you're doing too much requests to the weather api and
you will have to start paying for it very soon. You then decided to cache the results in a database table
so you can reduce the amount of requests.
public Weather getWeather(Date day) throws HTTPException, SQLException {
Weather w = getFromCache(day);
if (w != null) {
return w;
} else {
return getAndCache(day);
}
}
Now you have a problem, you can't add this new exception to the throws statement because you will most certainly break
your api's users code.
And if you think about it, your api's users are no interested if you had problems getting the data from the wheter api or
from your cache, they just want to be informed of errors. This is a very good case to wrap those exceptions in
a more generic one, like WeatherFetchException.
As you can see, it really depends...
The rule of thumb to me is, keep your exceptions meaningful and if you want to wrap them, do only when
it makes sense and when it doesn't remove the caller's ability to handle errors.
Wrapping exceptions just for the sake of it is most definitely not a good practice.

Testing if custom exception was thrown when a run time exception is thrown using mockito

I have this code where I'm catching some exception and throwing a custom exception instead.
#Override
public void config() throws CustomException{
File jsonFile = new File("config.json");
try {
ConfigMapper config = mapper.readValue(jsonFile, ConfigMapper.class);
try {
this.instanceId = Integer.parseInt(config.getConfig().getClientId());
this.configParams = config.getConfig().getConfigParams();
} catch (NumberFormatException ex) {
throw new CustomException("Please provide a valid integer for instance ID", ex);
//LOGGER.log(Level.SEVERE, "error initializing instanceId. Should be an integer " + e);
}
} catch (IOException ex) {
throw new CustomException("Error trying to read/write", ex);
// LOGGER.log(Level.SEVERE, "IOException while processing the received init config params", e);
}
}
I need to write a unit test for this and below is how I wrote it.
#Test
public void should_throw_exception_when_invalid_integer_is_given_for_instanceID(){
boolean isExceptionThrown = false;
try{
Mockito.doThrow(new NumberFormatException()).when(objectMock).config();
barcodeScannerServiceMock.config();
} catch (CustomException ex) {
isExceptionThrown = true;
}
assertTrue(isExceptionThrown);
}
But its throwing a number format exception and not the CustomException as I want it to be. But this makes sense as I'm using the mock object to throw the exception as a result of which my code logic is not executed. But if that's the case, how do I test this scenario? Please advice.
1.) Remove the line Mockito.doThrow(new NumberFormatException()).when(objectMock).config();
2.) Change the Client-ID in your JSON-File to something that cannot be converted to an Integer.
this.instanceId = Integer.parseInt(config.getConfig().getClientId()); will fail due to that and thus throw an exception.
One advice regarding names: The name of your test method should be what's written in the Java-Doc. Just name it "testCustomException" & explain the methods function in the Java-Documentation. There are Naming-Conventions in Java (click here) which are basically general guidelines.
Practicing these is very helpful as it allows you to quickly get into your code again after not working on it for a month or so due to the increased readability.

Correct way to handle method exception? [duplicate]

This question already has answers here:
Catching an Exception from a called Method
(4 answers)
Closed 7 years ago.
i seem to be a bit confused on how to throw exceptions and when it would be used to create your own exceptions.
i have this code and was wondering if i went about this the correct way
heres the method:
public void setHireYear(int year) throws Exception {
try{
if (year <= CURRENT_YEAR && year >= CURRENT_YEAR - MAX_YEARS_WORKED) {
hireYear = year;
}
else{
throw new HireYearException(year);
}
}catch(HireYearException e){
e.toString();
}
}
and heres the exception class:
public class HireYearException extends Exception
{
private int hireYear;
/**
* Constructor for objects of class HireYearException
*/
public HireYearException(int hireYear)
{
this.hireYear = hireYear;
}
public String toString()
{
return "Hire year cannot exceed Current year, your hire year is - " + hireYear;
}
}
why would throwing a custom exception be better than throwing pre defined exceptions?
Specific customs exceptions allow you to segregate different error types for your catch statements. The common construct for exception handling is this:
try
{}
catch (Exception ex)
{}
This catches all exceptions regardless of type. However, if you have custom exceptions, you can have separate handlers for each type:
try
{}
catch (CustomException1 ex1)
{
//handle CustomException1 type errors here
}
catch (CustomException2 ex2)
{
//handle CustomException2 type errors here
}
catch (Exception ex)
{
//handle all other types of exceptions here
}
Hence it provides you (benefits and why to create it)
1.specific exceptions allow you a finer level of control over your exception handling
2.Provides a type safe mechanism for a developer to detect an error condition.
3.Add situation specific data to an exception
Ideally this data would help another developer track down the source of the error.
4.No existing exception adequately described my problem
Source

Using specific try catch, error overrides

This is my Exception:
public class MyException extends Exception {
private String errorCode="Unknown_Exception";
public MyException(String message, String errorCode){
super(message);
this.errorCode=errorCode;
}
public String getErrorCode(){
return this.errorCode;
}
}
Now immagine the next scenario, the code is way too long to paste here:
1 I got a Presentation class made in Swing in Presentation package
2 In package calculations I made simple operations with few numbers from received database fields
3 In package connections I got the database connections
Trouble comes here:
-In presentation layer I catch all errors, like this:
try {
//here is a method called updateCombo() wich throws:
//throw new MyException(e.getMessage(),"ERROR_UPDATING_COMBO_BOX");
} catch (MyException ex) {
try {
//Here we process error code, if error is not defined, uses default errors.
processCode(ex);
} catch (MyException ex1) {
Logger.getLogger(Presentacion.class.getName()).log(Level.SEVERE, null, ex1);
}
}
processCode is a simple list with cases, like this:
private void processCode(MyException e) throws MyException {
switch (e.getErrorCode()) {
case "ERROR_UPDATING_COMBO_BOX":
lblErrorText.setText("Error updating combo.");
throw e;
case "ERROR_SELECTING_PRIMARY_KEY":
lblErrorText.setText("Error selecting PK");
throw e;
case "ERROR_OPENING_CONNECTION":
lblErrorText.setText("Error opening connection.");
throw e;
default:
lblErrorText.setText("Excepcion not defined: "+ e.getMessage());
e.printStackTrace();
}
This is the scenario, the connection fails in 3rd package and leads to this:
throw new MyException(e.getMessage(),"ERROR_OPENING_CONNECTION");
As I said, the error is thrown to the upper layer with throws clause in method header, this beeing 2nd package.
2nd package also throws a new exception to Presentation, because of failing connection:
throw new MyException(e.getMessage(),"ERROR_SELECTING_PRIMARY_KEY");
Presentation methods also throw this exception becase 2nd layer failed:
throw new MyException(e.getMessage(),"ERROR_UPDATING_COMBO_BOX");
The main problem:
Using debug i found out that the program does what it has to do. It gets to the connection layer and does this successfully:
throw new MyException(e.getMessage(),"ERROR_OPENING_CONNECTION");
But, in 2nd layer, calculations, if connection fails it throws a new exception:
throw new MyException(e.getMessage(),"ERROR_SELECTING_PRIMARY_KEY");
This is the problem:
throw new
throwing new exception overrides ERROR_OPENING_CONNECTION with ERROR_SELECTING_PRIMARY_KEY. When it gets to presentation due to its "throw new" overrides ERROR_SELECTING_PRIMARY_KEY with ERROR_UPDATING_COMBO_BOX, resulting in the final error shown in the screen:
lblErrorText.setText("Error updating combo.");
Is there any way to return to presentation once first error is caught without overriding by next errors?
Maybe I misunderstood the concept but I want to catch all possible errors because:
-If connection is OK but method in 2nd layer fails it should throw ERROR_SELECTING_PRIMARY_KEY.
-If 2nd layer (calculations) does it OK but there is error in presentation it should lead to ERROR_UPDATING_COMBO_BOX.
You can use e.getCause() which will return a Throwable and check if this cause belongs to MyException. In case it is, you can check the e.getCause() again recursively until you obtain the deepest error code in the stacktrace and perform the validation for this exception.
Here's an example:
public MyException getDeepestException(MyException e) {
Throwable t = e.getCause();
if (t instanceof MyException) {
return getDeepestException((MyException)t);
}
return e;
}
As pointed out by #RealSkeptic, in order to use this approach, you will need to add an additional constructor to your custom exception:
public MyException(String message, Throwable cause, String errorCode){
super(message, cause);
this.errorCode = errorCode;
}
And when throwing your exception, call the proper constructor:
try {
//...
} catch (SomeException e) {
throw new MyException(<a proper message should be here>, e, "ERROR_SELECTING_PRIMARY_KEY");
}
If I understand you correctly, if the exception caught by one package happens to be a MyException, you want the original MyException to be passed up, otherwise (if the exception is some other type of Exception) you want to create a new MyException.
In this case, you should have two catch clauses.
try {
// Whatever you do in the try clause
} catch ( MyException myEx ) {
throw myEx;
} catch ( Exception e ) {
throw new MyException(e.getMessage(),"ERROR_SELECTING_PRIMARY_KEY");
}

Categories

Resources