Handling Errors

This article introduces you to the error and exception handling mechanism of the JsaPar library. This article assumes that you already have followed the instructions in the setting up article of this website, and that you have familiarized yourself with the API of the JsaPar library explained in the getting started article of this website. If not, please make sure that you have read these articles before continuing reading this article.

A basic introduction to Java exceptions

What is an exception?
An exception occurs when the normal (e.g. intended) behaviour of the program (e.g. program control flow) differs in such a way that the program cannot continue executing the normal programmed code due to an exceptional situation. For example: the normal behaviour of a program could be to open a file on the filesystem, but because of the fact that the file isn't found on the filesystem, although that was the intended behaviour of the program, the program can't continue normally without having read the file first. The program is confronted with a situation it can't solve, so this is an exceptional situation: the program cannot ignore and continue this situation and thus needs to recover from it. Therefore, the program throws an exception to indicate that such situation occurred. When an exception occurs during the execution of the program, the default behaviour is to terminate the program and to print an exception message. However, Java makes it possible to "catch" the exception and program a response different from simply letting the program crash. This is called exception handling.

In what kind of situations does an exception occur?
Broadly speaking, there are three different situations in which an exception occurs. These exceptions occur due to:
  • Programming errors
Exceptions that are caused by programming errors cannot be recovered from within the Java code. For example: a program cannot recover from a NullPointer exception or an IllegalArgument exception. 
  • Client code errors
Exceptions that are caused by client code errors can be recovered from, as long as there is useful information provided in the exception so that the client code knows what alternate actions it can take to recover from the exception. For example: while parsing an XML document that is not well-formed, an exception is thrown. When the exception contains useful information about the location in the XML document that causes the problem, the client code can use this information to take recovery steps. Exceptions that occur in this category are mostly caused due to violating the API contract: the client code attempt to do something that is not allowed or wasn't intended to be used as it is programmed.
  • Resource failures
Exceptions that are caused by resource failures are the most common exceptions that can occur. These exceptions occur when something beyond the control of the program happens in which the program doesn't have any influence. For example: the system runs out of memory or a network connection fails, or the files that were expected aren't available on the filesystem. The response of the client code to resource failures is context driven. This means that for some resource failures the client code has no choice but the quit the program, while for other resource failures the program can choose to retry in a predefined time period to detect if the resources eventually have become available, so it can continue executing the program in the expected control flow.


What types of exceptions are there?
Java defines two types of exceptions:
  • Checked exceptions
These kind of exceptions represent invalid conditions in areas outside the immediate control of the program (invalid user input, database problems, network outages, absent files).
Checked exceptions must be handled by the client code. It is a contract between the client code and the API and cannot be ignored. The client code must handle these exceptions by either catching the exception itself (using the try/catch clause) and handle it properly, or by forwarding it outward using the throws clause and letting the caller method handle the exception.
Checked exceptions are inherited from the java.lang.Exception class and are exceptions in which the client code has a good chance to recover from.
  • Unchecked exceptions
These kind of exceptions represent conditions that, generally speaking, reflect errors in your program's logic and cannot be reasonably recovered from at run time. For example: invalid arguments passed to a non-private method.  Unchecked exceptions do not have to be handled by the client code, but sometimes they can be handled in the client code if you run into a situation in which it actually is possible to recover from. Unchecked exceptions are inherited from the java.lang.RuntimeException class and are exceptions in which the client code has a really small chance to recover from.
 
How the JsaPar library handles exceptions

The JsaPar library has build-in support for dealing with exceptions that can occur while processing data sources. Next to dealing with these exceptions, the JsaPar library can also produce a list of errors that occurred during the process of parsing and/or producing data sources. 

When working with the JsaPar library, you can choose if you (as a caller) want to get an exception upon the first error or if you want to get a list of all errors at the end of parsing. In some situations it is useless to continue with the parsing process when an exception or error occurs. In other situations it doesn't matter if you get errors while parsing, as long as the number of errors are limited to a few errors. If more errors occur than the predefined threshold level for errors, the library is able to throw an exception to stop the parsing process, because it has become useless to continue with the parsing process.

The JsaPar library makes use of Checked Exceptions and therefore the client code must handle these exceptions accordingly. The main exception of the JsaPar library is called:
  • JSaParException (org.jsapar.JSaParException)
All other JsaPar library related exceptions are derived from the main exception and are called:
  • SchemaException (org.jsapar.schema.SchemaException)
  • ParseException (org.jsapar.input.ParseException)
  • MaxErrorsExceededException (org.jsapar.io.MaxErrorsExceededException)
  • OutputException (org.jsapar.output.OutputException)
TODO


- Descriptive errors when parsing goes wrong.
- Locale errors (if possible), Date errors, etc
- List of possible errors you can get
Parsing errors can either be handled by exceptions thrown at first error or the errors can be collected during parsing to be able to deal with them later.

The JsaPar library in action

To demonstrate the possible options you have as a developer for dealing with exceptions and errors, the following examples are discussed in detail.

Handling exceptions

Todo deal with exceptions
- How to handle JsaParExceptions nicely 
- JSaParException

Cell Exceptions: duplicate cell name, value not parsable, value not set, 
Line exceptions:
Document exceptions:
Parse exceptions:
Output exceptions:
Schema exceptions:
Error exceptions: max number of errors exceeded,




Handling errors

Todo deal with error messages

- CellParseError
- LineErrorEvent
Once a Line is completed, a LineParsedEvent is generated to all registered event listeners. If there is an error while parsing a line, a LineErrorEvent is generated to all registered event listeners.
If there is an error reading the input or an error at the structure of the input, a JSaParException will be thrown.