Handling a general exception in constructor - java

Is there a way to handle an exception in the constructor.
Everytime I use the getter into another method I have to declare the exception again. I tried a try/catch block inside the constructor but still asking for other method to declare the exception.
public Question() {
try {
this.file = new File("questions.txt");
} catch (Exception e) {
System.out.println("Could not find file");
System.out.println("Check file path is correct");
}
counterIndex = 0;
questionSetup();
}
public Question() throws FileNotFoundException {
file = new File("questions.txt");
counterIndex = 0;
questionSetup();
}
public ArrayList<String> getQuestionArr() {
return questionArr;
}
public File getFile() {
return file;
}

Throw it from the constructor, and handle it anywhere else. When a constructor encounters an exceptional situation, it should throw an exception instead of continuing along and fully constructing an object.
Imagine if FileInputStream didn't throw a FileNotFoundException.
FileInputStream fis = new FileInputStream("~/iDontReallyExist.bin");
// appears to work
// then later, long after you've instantiated `fis`
fis.read(buffer); // <-- boom?
Constructors can and should throw exceptions whenever something breaks. Code calling the constructor (or higher up in the stack) handle it as they see fit (trying again, failing, etc.). As a bonus, the half constructed object becomes available for garbage collection without you needing to be too concerned about it.
Assuming that Question() throws a FileNotFoundException, you can handle an error something like this (I don't know your real app obviously, so this is made up as an example of error handling):
Question loadQuestion(int id) throws FileNotFoundException {
return new Question(getQuestionPath(id));
}
called by:
Set<Question> getQuestionsByCategory(QuestionCategory category) {
Set<Integer> ids = getQuestionIds(category);
Set<Question> questions = new HashSet<Question>();
for (Integer id : ids) {
try {
questions.add(loadQuestion(id));
} catch (FileNotFoundException ex) {
somelogger("File not found loading question ID " + id, ex);
throw ex;
}
}
return questions;
}
and finally
public static void main(String[] args) throws FileNotFoundException {
Set<Questions> questions = QuestionsLoader
.getQuestionsByCategory(QuestionCategory.valueOf(args[0]));
}
In this example, I log it in code responsible for loading questions by category, then re-throw it to let it blow up. I chose to do that because not being able to open a local file seems like something fatal here, but you're not constrained to do that. You could instead simply not include the question in the returned results, or ask for a different path to search. The bottom line of what to do upon an error is ultimately in context of what you need.

Related

Java mp3 file errors

I am new to programming and trying to insert the mp3 file on Mac, but I have errors with these codes. I have been looking for solutions for a long time but I was not able to find the right answers. I would like to know what I did wrong.
import javazoom.jl.player.Player;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
public class Music {
public static void main(String [] args) {
String filename = "src_music_typing.mp3";
MusicPlayer music = new MusicPlayer(filename);
music.play();
}
}
class MusicPlayer {
private final String mp3File;
private Player jlPlayer;
public MusicPlayer(String mp3File) {
this.mp3File = mp3File;
}
public void play() {
try {
FileInputStream fis = new FileInputStream(mp3File);
BufferedInputStream bis = new BufferedInputStream(fis);
jlPlayer = new Player(bis);
} catch (Exception e) {
System.out.println("problem file is " + mp3File);
System.out.println(e.getMessage());
}
new Thread() {
public void run() {
try {
jlPlayer.play();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}.start();
}
public void close() {
if(jlPlayer != null) jlPlayer.close();
}
}
Problem:
problem file is src_music_typing.mp3
src_music_typing.mp3 (No such file or directory)
Cannot invoke "javazoom.jl.player.Player.play()" because "this.this$0.jlPlayer" is null
The error is telling you simply that src_music_typing.mp3 does not exist; evidently you aren't running this in the directory you think you're running it in. Trivial solution: Make that path string (String filename = "src_...") an absolute path instead.
NB: It's a cavalcade of problems, here. Your code is bad and it leads to inefficient error messages. Inefficient enough to confuse you, for example.
You should never catch an exception just to log it and then blindly continue; I know a ton of code snippets do this, but that part of them is just bad. You don't want to do that - dealing with an error by blindly continuing on is, obviously, a really silly thing to do!
The right way to deal with exceptions that you don't explicitly know how to handle is instead to just throw them on. your play method should be declared as throws IOException, as this is inherent to your API design, this is fine (it's inherent because your music player class as a property that represents a file name, and anything file related is expected to throw IOExceptions, hence, fine - not leaking an abstraction).
Then the whole try/catch bit can just go away, yay! Your code is better and shorter and easier to understand, win win win!
Because you didn't do that, and you just run blindly on, you get a second error that is complaining about attempting to invoke play() on a null pointer. This error is meaningless, in that it's merely a symptom, not the cause. The cause is the first error message. This is one of a few key reasons why 'keep blindly going' is a really bad idea - it means you get a ton of meaningless, confusing errors after the actual problem, resulting in a ton of error output, most of which is just hiding the actual problem.
If you can't throw them on, a distant second best solution is to put this in your catch blocks: throw new RuntimeException("uncaught", e);. This preserves all error information (type, message, stack trace, causal chain - all of it), and still ensures code does not blindly continue when your method is an unknown (to you) state. If you have an IDE that inserts catch blocks for you, update its template.
NB: main can and usually should be declared as static void main(String[] args) throws Exception {.

Unhandled exception type Exception in Eclipse

I have the class Parser in Java like below:
public class Parser {
public ArrayList<MetroStop> listeArrets;
public Parser() {
this.listeArrets = new ArrayList<>();
}
public MetroStop creerArret(String [] parts) {
MetroStop arret = new MetroStop ();
arret.identifiant = Integer.parseInt(parts [0]);
arret.longitude = Double.parseDouble(parts [1]);
arret.latitude = Double.parseDouble(parts [2]);
arret.nom = parts [3];
arret.destination = parts [4];
arret.moyen = parts [5];
return arret;
}
public void parse(String fichier) throws Exception {
try {
Reader reader = new FileReader(fichier);
BufferedReader br = new BufferedReader(reader);
String line;
while((line = br.readLine ()) != null) {
String [] parts = line.split("#");
MetroStop arret = creerArret(parts);
listeArrets.add(arret);
}
br.close();
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
}
}
I also have the Main class:
public class Main {
public static void main(String[] argv) {
Parser teste = new Parser();
teste.parse("ratp_arret.csv");
}
}
When I run the Main class as Java Application i get this error:
"Unhandled exception type Exception", which points to the second line of the main() method.
The file ratp_arret.csv is located in the src folder, which is also the working directory.I am using Eclipse.
I don't understand where this error comes from.
Thank you for your help!
You call teste.parse(someString), where teste is an expression which has type Parser. That means this is a call to the method parse(String) in your Parser type....
and that is declared with throws Exception.
Exceptions are a mechanism to convey alternate return options. The parse method can run its course in one of two ways: It can 'return', in which case it returns nothing (void), or, it can 'throw'. What it can throw is limited by its throws line - in this case, it can throw just about anything (Exception is the supertype of almost all things you can throw).
The way java handles this is that your code needs to handle every possible way a method can conclude.
So, you need a 'path' for your code when the parser() method returns (this is trivial; it's a void method, you get that 'for free', you don't need to write anything special for this), but you also need a path for that other exit scenario: When it throws something. You get handling of RuntimeException for free, but for others, you have two options:
catch it:
try {
teste.parse(someString);
// this code runs in the 'return' case.
} catch (Exception e) {
// this code runs in the 'throws' case.
}
this would imply you know what to do when your parse method decided to exit via the throws path.
Alternatively, you fix this by having your main method also 'fork', and decree that it has two ways to finish: Either via the return route or the throw route:
public static void main(String[] args) throws Exception {
teste.parse(someString);
}
// this main method has declared that it has two separate
// exit routes. 'return', and 'throws something'.
java will start an application by running its main method, and java can deal with a main that has two alternate exit routes (return, or throw something). It handles the 'return' route by doing nothing. It handles the 'throw something' route by printing the type of the exception, the message, the stack trace, and the entire causal chain. That is an excellent default, and you should not attempt to come up with a different one by e.g. catching that exception and attempting to 'log it'.
This: Just add throws Exception to your main method declaration. Put the throws Exception back on your parse method, ignore #Eritrean's advice.
NB: All methods are inherently declared as if they said throws RuntimeException, Error (as in, any error and any runtimeexception can be thrown without writing a throws clause for it, as all methods implicitly have that clause baked in already), this is why I said earlier that RuntimeExceptions are 'handled for free'. The idea is that all exceptions that subclass RuntimeException are things that are so universal or so unlikely, it would be unwieldy to force management of this onto the programmer. That's why you never need to write throws NullPointerException or throws InternalError.
public void parse(String fichier) /*throws Exception*/ {
try {
// ...
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
}
You throw RuntimeException. This is called not-checked exception and it's not mandatory to declare these exeptions in the method declaration and catch it when calle the method.

Reading from file in Java is throwing a `NullPointerException` [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 6 years ago.
I have made a main class as well to run it, but it is throwing out an NPE NullPointerException at the readFile() method. I'm not sure why this is occurring.
/* this code is to read from a file testfile.txt which is already made beforehand with data in it*/
import java.io.*; //imported files
import java.util.*;
public class file_read {
private Scanner x; //for reading from file
public void openFile() {
try {
x = new Scanner(new File("testfile.txt"));
} catch (Exception e) {
System.out.println("error occurred");
}
}
public void readFile() { //error in this method(NPE)
while (x.hasNext()) {
String a = x.next();
String b = x.next();
String c = x.next();
System.out.printf("%s %s %s \n", a, b, c);
}
}
public void closeFile() {
x.close();
}
}
public class file_read_main {
public static void main(String[] args) {
file_read obj = new file_read();
obj.openFile();
obj.readFile();
obj.closeFile();
}
}
This is one class. The other class is already made having main() in it having object of this class as well as calling of the methods from the object.
The problem is that x is null.
Based on the code that you have shown, this can only be because an exception is being thrown in openFile(), and you are ignoring it.
Make openFile throw its exception:
public void openFile() throws IOException {
x = new Scanner(new File("testfile.txt"));
}
(you will need to add throws IOException to your main method too)
Now the fact that an IOException has been thrown will stop your code executing, so it won't try to read the file.
Assuming you've got no default exception handler set up, you will also get the stack trace of the exception, which will include details of why the exception was thrown.
As a general principle about exception handling, don't catch Exception, unless that's really the exception that you really need to handle. It catches all exceptions, and might accidentally catch certain exception types which really should be handled separately.
You should also not just swallow exceptions unless you are really sure that is the right thing to do. The bare minimum you should do with an exception is to print its stack trace in the catch:
e.printStackTrace();
This is not the best choice in the current situtation, however, since you actually need to stop further execution in the calling method: propagating the exception is a better choice.

Thumb rule for when an exception should be advertised and when should it be handled

I have method x that calls another method inside it called y which throws an exception MyException. At this time I have 2 options, either to advertise my method x with the exception MyException ... like
public void x() throws MyException {
// call to y
}
(since y is advertised with throws clause like this...)
public void y() throws MyException {
// code
}
or wrap the call to y in my method x in try catch block and handle it ? like this..
public void x() {
try {
// call to y
} catch (MyException e) {
// handle exception
}
}
what is the thumb rule ?
If your method can keep the contract with its callers, regardless of the exception, then the exception is something it can, and probably should, handle.
If a caller would be confused to find out they said "do x", and there was an internal problem with the "y" part of doing "x", because "x" didn't really get done, then you should expose the exception (or some other exception which has a MyException as the cause).
And - consider if the caller can reasonably handle the exception, or if there's any reason for the program to continue, and if the answer is no to either, consider using a RuntimeException or Error, respectively.
That's what I'd say, anyway.
The answer is pretty simple:
If you can deal with the inner exception, you should catch it and do something reasonable
If you can not deal with it, you have two choices:
If the exception is implementation specific, catch it and throw an exception acceptable to your caller (typically wrapping the actual exception)
If the exception is in your caller's domain, declare as throwing it and let your caller deal with it
Here are some examples of each type:
Example 1: Dealing with it:
public void deleteFile(String filename) {
File file = new File(filename);
try {
file.delete();
} catch (FileNotFoundException e) {
// No big deal - it was already deleted
}
}
Example 2: Wrapping it:
public void changePassword(String username, String password) throws UserUpdateException {
try {
// execute SQL to update the password
// but storing the user in a DB is an imlementation choice
// we could use a file on disk or a remote web service to store user info
} catch (SQLException e) {
throw new UserUpdateException(e);
}
}
Example 3: Doing nothing:
public void insertIntoDatabase(Record record) throws SQLException {
// execute SQL on the database
// using a DB is implied - let the exception bubble up
}

Java casting an exception (not class cast exception)

When an exception is caught in java is there a use case for casting the exception to a new type? Or is the standard
throw new DiffException(e)
The only way to do it. I apologize if I'm overlooking something but the only search results I get are for "ClassCastExceptions" Which is obviously not what I'm looking for
I believe you meant 'exception wrapping'.
There's no other way to do it - you create a new instance of Exception using a constructor which takes another exception as cause. This works thanks to 1-arg constructor of java.lang.Exception. The typical implementation of custom exception type (like your DiffException) declares such 1-arg constructor too.
Well, if the exception caught (e in your case I suppose) is a subtype of DiffException, you could of course cast it like
throw (DiffException) e;
but I doubt that's what you want to do, since it doesn't make a difference (the e will still have the same runtime type, even in the receiving end).
So the answer is most likely, no, there is no other, equivalent way, of doing
throw new DiffException(e);
than doing just that.
It should be noted however, that doing new DiffException(e) is not called casting but, wrapping, or chaining the exception.
If I understand you correctly here is the use case I am thinking about.
expression:
new FileInputStream("the path");
may throw FileNotFoundException if the file does not exist. FileNotFoundException extends IOException, so you could write code like:
public void readFromFile(String path) {
InputStream in = new FileInputStream(path);
// do something....
}
Now you can call this method as following:
try {
readFromFile("myFile");
} catch (IOException e) {
if (e instanceof FileNotFoundException) {
FileNotFoundException fnfe = (FileNotFoundException)e;
// do something
}
// do something else
}
But I'd recommend you create separate catch blocks for FileNotFoundException and for IOException (at least for this use-case):
try {
readFromFile("myFile");
} catch (FileNotFoundException e) {
// do something with FileNotFoundException
} catch (IOException e) {
// do something with IOException
}
This code does not contain instanceof, casting and other ugly stuff.
Since you mentioned use cases, the common one in Java is wrapping a checked exception as unchecked; this is appropriate when there's no way the checked exception can occur, such as here:
public static Reader getUTF8Reader(InputStream is) {
try {
return new InputStreamReader(inputStream, "UTF-8");
} catch(UnsupportedEncodingException e) {
// should never happen since UTF-8 is guaranteed to be available as per
// http://download.oracle.com/javase/6/docs/api/java/nio/charset/Charset.html
throw new RuntimeException("UTF-8 not available", e);
}
}
Without wrapping the exception, you'd either have to swallow it (which feels wrong) or declare the method as throws UnsupportedEncodingException which forces anyone using it to catch the exception that will never be thrown. Wrapping it, there's no onus on the caller to handle unlikely cases, yet we're protected in the unlikely event that UTF-8 isn't available on some obscure platform in the future.

Categories