I have a Java program that parses several different input files. Even when an error is found in this input files, parsing could still continue and collect several other errors too. So what I want to do is instead of throwing and exception and stopping parsing process, I'd like to register the exception to somewhere, and then continue parsing and collect several other errors in similar way, then in the end I want to check if any errors are reported, and fail or continue depending on this.
Of course I can always do this manually by writing ExceptionRegister or whatever classes but I want to know two things:
1) Is there a problem with this approach? Do you know any alternative designs for what I want to do?
2) Is there a standard way of doing this? (e.g. instead of rolling my own classes I'd like to use built-in functionality if possible)
Thanks
EDIT: I don't know why but someone just removed his answer just before I accepted his answer. Anyway, I think simple data structures should work. Basically, I'll write an exception class that collects several error messages. Then I'll call it's throw method which throws itself if it has at least one error message registered.
EDIT2: Here are more clarifications. My problem has nothing to do with parsing. Parsing was just an example because my program does some parsing. Think this: I'm running an algorithm and in case of an error, I can continue the algorithm to collect more errors so that instead of printing one error and when it's fixed, printing second error, I can print this two errors together.
Exceptions should really be used when you can't handle the input anymore. They are the special case where your code says "I give up, I'm missing some information or I wasn't meant for this". This is a grey area on how to define such cases, but the usual philosophy, as put by Bill Venners in this (old!) article is:
Avoid using exceptions to indicate conditions that can reasonably be
expected as part of the typical functioning of the method.
In your case, it sounds like the content you have to parse might be incorrect, but this is expected by your program and doesn't break enough the contract to stop the parsing. On the other hand, an acceptable exception would be valid to use if an error in the syntax of the input causes the rest of the interpretation to fail, for example.
But people still uses exception because they are quite convenient for stopping execution and going up the stack without going in the tedious details of flowing through returns of results. But on its counterpart, they can have tricky results as you leave some unattended state in some objects.
Your requirements sounds more like a validation pattern is required than one single exception that could cause the processing to stop. One exception to stop all processing: if you throw one, the rest will be ignored. But you suggested that you would collect them instead of throwing those. So I'd say, in that case, why use exceptions at all? It seems you do want to return proper results and not stop the program's execution.
Because if you still go down this path, you could have a collection of exceptions to throw at the end. Which one do you throw? Which one takes precedence, in the Exception collector you created?
Take the example of Eclipse, which has this gigantic platform to handle with a massive collection plug-ins contribution. They use a proper communication channel to log any warning and errors, either in problems pane or through the execution of background task. The latter's execution will usually return an IStatus object or a variant. Based on this IStatus object, the code that receives the status decides to act upon it.
Hence personally, I'd develop a similar object that would collect all necessary user's errors (and not program's errors), that does not break the program's execution and an acceptable part of the contract. This object can contain the severity of the error, its source, a hint on how to fix it (this can be a string, or even a method that contains a pinpointing logic for showing the error or possibly a partial automated fix), etc... Once the execution is done, the parsing's result will get these status objects and act on it. If there are errors, inform the user through the UI and log it as well.
So it's basically the same approach as you initially suggested, minus the exceptions and minus the commodity of jumping through the stack that could lead to nasty side-effects and very difficult to debug errors.
I think I understand now. What you are actually trying to do is to collect the parse errors (which you are representing as exceptions) and continue parsing the current input file.
There is no standard way to do this:
The "exception register" is really nothing more than a list of parse error descriptors ... presumably some parser exception. If you can catch the exception at the appropriate point, it is trivial to add it to the "register".
The difficult part is the functionality you are not talking about:
How to capture the location of the error
How to get the parser to continue parsing when it gets a parser error.
The solutions to these depend on how you have implemented your parser.
If you are using a parser generator, there is a good chance that the PGS documentation explains how to implement this.
If you are implementing the parser by hand, you will need to roll your own code to track error locations and do syntax error recovery.
Basically, I'll write an exception class that collects several error messages. Then I'll call it's throw method which throws itself if it has at least one error message registered.
That sounds like an abuse of exceptions. A better idea is to accumulate the errors in a list, and then create / throw the exception if the list is non-empty. Use a static method in a helper class if you want to avoid duplicating code.
An exception that conditionally throws itself is (IMO) bizarre! And creating lots of exceptions that you are unlikely to throw is likely to be inefficient. (Depending on the JVM, the expensive part of exceptions is often creating the exception and capturing the stack frames. The expense can be significant.)
Related
Are exceptions like goto in c don't use it if you don't have to or is it OK to use them as much you want to, and why?
Are they hard on CPU, memory or something else?
You should regard exceptions as a tool that can help you make good software design, similar to data encapsulation (private fields with Getters/Setters), inheritance, interfaces, etc.
The idea of the exception concept in Java is to give you a good way of moving error handling to a spot in your code where it makes most sense. When you face a problem at some line of code, then the first thing you should ask yourself is: Should this method/class that I have here be responsible for handling the problem, or is there a better, more high-level place in my software that should handle it? If you find the latter to be the case, then throwing an exception to that higher-level instance is good design.
Think of it as this: Let's say someone at your work place gives you a pack of bills and tells you to add up the total billing amount. And then in the middle of the bills you find another document that is something completely different. In that case, it would make more sense to go to the person who gave you the pack of documents and let them handle it, instead of deciding for yourself what to do with it, because you may not know what exactly to do.
Example in software: Let's say you have a method that expects a birth date and should calculate the age of the person (difference to current date). But then you find that the given date is incorrect, for instance because it is in future. This method should not deal with fixing the problem, because you might not know how. Is this program a console program and you should print an error, or will it have a GUI? So, you throw an exception to a higher level of the application that knows if there is a GUI or not, and thus whether to print an error to console or show a dialog in the GUI. That's just a simple example, but I hope you get what I mean.
To sum up: Exceptions are nothing "bad" in Java. When used properly, they are a good thing that help you avoid putting responsibilities into objects that they shouldn't have.
...don't use it if you don't have to or is it OK to use them as much you want to...
According to Joshua Bloch's Effective Java:
Exceptions are, as their name implies, to be used only for exceptional
conditions; they should never be used for ordinary control flow.
In order to fully understand this, let's take a look on Java exception. In Java we can find three types of exceptions: checked exceptions, runtime exceptions, and
errors.
Checked exceptions: as their name implies, they should be checked/treated by the developer. Moreover, the compiler forces you to handle this exceptions by try...catch or propagating them upwards by marking the method with throws keyword. These kind of exceptions usually extend the builtin `Exception' class.
Unchecked exceptions: in this group enter both runtime exceptions and errors. The difference between checked exception and unchecked exceptions is that the compiler does not forces you to handle unchecked exceptions. Since they should be used to indicate programming errors, usually it is a good idea to not catch them at all and focus on preventing them. Errors are reserved for use by the JVM to indicate critical failures which usually prevent your program to be recoverable. All of the unchecked
exceptions should subclass RuntimeException class.
So, to give you a response to your first question, it is OK to use exceptions as long as it makes your code readable, more understandable. Moreover, you should be able to deal with exceptions, since compiler will force you to do so. This does not mean that you should throw exceptions whenever you want.
Now let's talk about performance. To repeat myself, exceptions should be used in exceptional cases. This means that they are not as performant as a single if..else would be. Using them wisely, you wont really notice a performance hit, overusing them can cause problems. Exceptions should never be used for control flow (gotos can be used for). In case of memory, every exception creates a new object, which should contain some information about the exception itself. Creating many exceptions would result in occupying more memory, but I don't think that this can be a problem nowadays.
Should I ever use exceptions in java if I can solve problem without
them?
It depends, and is up to you on deciding against or in favor of them. Usually, exceptions are thrown to notify the lack of something (example: no money to withdraw from a credit card, non-existent file to open, etc.) In order to avoid using exceptions in these cases, it is a good idea to return on Optional of something.
This answer is based on Joshua Bloch's Effective Java book. For more information I suggest reading the Exceptions chapter.
Lets say your program is going to do a variety of math computations and want to know the available exceptions that are possible to capture to see if any are applicable.
Or, the program will be doing a lot of file i/o and other things and you want to capture specific exceptions instead of simply capturing Exception.
Maybe you may want to know if one application is even applicable in the scenario being coded.
What is the recommended way to go about researching what exceptions are available to be captured when generating code to do specific activity?
Using a IDE like Intellij or Eclipse will let you know most of the exceptions that the library code you are using throws, depending on it's javadoc(Like FileNotFoundException) and majority of the times, these are the exceptions that you should worry about.
Other exceptions like divide by zero, null pointer exception will certainly depend on the code you are writing. For example if you getting an object from a different class, you might want to check if it is null before doing any operations on it. Similarly if you are dividing by something, like K/X , you should have an idea whether X is ever going to be 0 or not.
The recomended way is to look into the javadoc of that method.
Hopefully the software author of that code wrote the javadoc in the recomended way, to also list the Runtime Exceptions that a method throws.
You can usually find this information in the Docs for the method you want to use. It will tell you what exceptions it can throw in what cases. There is no general purpose "find all exceptions" technique. This is probably a good things, because if you don't know how or why an exception is created, you probably don't know enough to handle it.
You can trace through the source of the code you are calling to find all the specific exceptions. The problem with this is that the time this takes esp since it could change between different versions of software is very high.
In general you can trust the Javadoc for broad checked exceptions, but this usually won't tell you about all specific exception or all RuntimeExceptions. (Including all future exceptions)
Note: you may wish to take different actions based on the message as well as the type of exception.
For this reason I suggest you focus on the specific exceptions which you handle differently, and have a catch all IOException or similar for unexpected exception which by their nature mean you can't know how to handle them.
There are two types of exceptions, checked and unchecked. If you don't handle checked exception you will get a build failure. You can identify checked exception if you are using any IDE. But unchecked exception are bit tricky and you may need to refer the API documentation to understand what they are, because unless it's thrown you may not know that exception can occur. Again some IDEs give you hints based on your code, for example class casting, null checking.
In a standard J2EE web application , assuming that class load times during app startup is not an issue, which would be a better approach in terms of maintainance, performace and usability ?
The first approach involves creating different exception classes, each to denote a particular error that occurs in the application. The class names are self explanatory, and that'll be used to provide error messages.
(UPDATE : The number of classes is about 30 as of now, and it'll continue to increase in the near future, probably upto 70 or 80 atmost)
The secodn approach involves creating one exception class, and a bunch of exception codes where each code represent a particular error in the app. The error codes are obtained from the exception, and is used to provide error messages.
It is more or less dependent on your business needs.
From my point of view, having multiple custom exception classes is the right approach to go.
Learn from Java, how many it manages.
In any given application there can be n type of validations, few can be clubbed under one group, few into another, but fitting everything into single does not solve the purpose in terms of logic and business.
let say,
UserAuthenticationException
Cases it can cover up, and give different error messages for different cases.
1.) Invalid username/passwords
2.) Session timeout
3.) Multiple active token of same user in different machines etc...
Later playing with instanceof or creating handlers of say different exception classes is much more easier rather playing with messages.
The choice is ultimately up to you, as both can be valid. I personally find it is better to make many custom exceptions, particularly if they are going to be used multiple times for the simple fact that if I want to change the error code or message a certain type of exception "File did not successfully upload" or "Item not found" or whatever the case may be, I only have to do it in one place, the custom exception, and not in every place which uses it.
This also allows you do catch those specific exceptions as the are thrown in other parts of your code. Perhaps you need to do extra work if the exception was a "File not found" exception, in which case you can catch only those exceptions that you want to handle in different ways - this would be much more difficult if they were all the same class.
Classes exists in OOP for a reason and you should take advantages of those reasons.
From the code maintabaility point of view, the first approach, as it results in cleaner/simpler code. The name of the exception class gives you the cause of the problem without having to inspect the attributes of the exception class.
From the performance point of view, the second approach, "fewer exception classes mean a smaller
memory footprint and less time spent loading classes" (Effective Java, item 60). Keep in mind however, that "premature optimization is the root of all evil" so until you confirm your application has performance issues do not try to optimize it.
Most exceptions within an application are handled by some generic recovery; probably involving generating a log file and killing or restarting the process. There's no reason for these to be different types.
In the less usual case where a specific recovery procedure is expected, there should be a specific error class for that procedure.
I am a newbie with designing stuff though I have some experience as a developer. My question is related to the statement -
"It is always a good practice to design the exception hierarchy at the start of the project"
After much of reading and researching the definition of a checked and unchecked exception is well clear.
However, I still wonder what is the best practices in designing the exception hierarchy for an application. Is the below approach right?
Create your own application specific top level exceptions
MyAppRuntimeException
MyAppCheckedException
Subclass MyAppCheckedException with all your business exceptions where you want the caller to take a specific exception. For example
TryWithADifferentInputException - This is not the right input, correct it
TryAlternateServiceException - This service is not available, but you can choose another service that will do the job
Similarly subclass your runtime exception which spiral up and are captured only by something like the spring exception resolver and display appropriate message on front end.
Another thing that bugs me is how to come up with most of the exception scenarios at the start of the project. What should be the strategy to do so.
Hello hailMurphy and welcome to SO!
IMO, it is not necessary to design an entire exception hierarchy for every app. Rather, you should only introduce new exceptions if none of the existing stock ones adequately address the error you're encountering.
Your TryWithADifferentInputException for instance could probably easily be replaced with an IllegalArgumentException or possibly IllegalStateException. I find that 99% of the time, I'm well able to do with the existing ones.
As for knowing which exceptions to expect before you actually start writing code: The complex parts of your program, such as class structure, algorithms, protocols, etc. should be thought out and documented before you actually fire up your IDE and get hands-on. UML is a common way to do this. During that process, as you're pen-and-papering your algorithm or protocol, try looking at border cases (what happens when this value becomes zero? What if this argument is null? Will my algorithm still work? Good! Will it break? Exception!) and playing devil's advocate (what if the network connection breaks down halfway through my protocol? Can I recover from this, or does it leave me in an unrecoverable state?) you should be able to see exception scenarios.
If you do find yourself in need for creating custom exceptions, derive them directly from whichever ancestor seems most fit - Error, IllegalStateException, RuntimeException, IOException, etc. Don't create your own complete hierarchy unless there is a scenario where you need to only catch all of your own exceptions and none of the stock ones. Honestly, though, I can't see a scenario where that might be useful.
On a more general note, exceptions should be a "last resort" to deal with errors that can't be otherwise recovered from, and not as a form of control flow. If you're expecting something to happen naturally as part of your application (such as bad user input), you should generally not deal with it through exceptions. If you have an algorithm that breaks unrecoverably in a lot of cases, it can be an indication that you haven't found the right one yet.
Well, I am not going to answer all of your questions, but just the parts that I know based in my experience.
The idea of create the exceptions at the begining just have sense if we have the design of the app really clear. I mean, we have to know the flows of the app and what could happen. If we dont know the design more than 80% probably we will change many things, including exceptions hierachy, many times.
Furthermore, If our app is designed correctly and at the coding stage a new exception appears, should be easy the addition in the exceptions tree.
Well I hope be clear for you.
Bye
Which is a better approach to exception handling and why?:
(1) Defining a single exception for the whole application which takes a string message and displays it. Use this exception everywhere with a specific message appropriate to the scenario.
I have no idea why this is not appropriate.
(2) Defining a new exception class for each different case in the application.
I feel this is not appropriate because there are cases where the exception is at just one place in the application. e.g. amount entered is -ve Is it ok to create a whole new exception class just for a single case in the app ?
Define a new exception for each kind of error that matters to your user. So, for example, ideally you should catch NullPointerException inside your program, and turn it into a CustomerLookupException to that the user level of the program can report "Software error retrieving customer." Exception chaining is handy for this, as you can pass along the original exception as well.
The whole Java Tutorial on exceptions is a good resource.
Definitely defining new exception for all different cases.
Imagine you are implementing an interpreter/compiler. You gonna have modules as SemanticVerifier, Interpreter, CodeGenerator (and others of course). You want to know what kind of exception gonna be thrown when your program crash. Oh there it's Semantic! there look it's a bug in the Interpreter! And you want the user to know so he can report a more precise bug.
I personally think it leads to a better design if you have separate exceptions for every module.
You should define a new exception for each case.
The reason is so that each Exception can be handled independently.
For example, catching the Exceptions differently allows you to either continue in some cases, or end in others.
in my view your 1st option is more suitable
(1) Defining a single exception for whole application which takes a string msg and displays it. And using it at all places with appropriate place specific message.
Even i am using a single exception in the application. If you create separate exception for each type it will increase complexity. It will have lot of redundant code.
For denoting different type of exception, you can pass a parameter(type or something) in the common exception itself.