APIDesignPatterns:Exceptions

From APIDesign

(Difference between revisions)
Jump to: navigation, search
(New page: TBD: just being created as a response to query by Casper Bang: ''I was curious as to know how come, in a book strictly about API design in Java, you do not mention exceptions (particular ...)
(Nothing special)
Line 7: Line 7:
== Nothing special ==
== Nothing special ==
-
TBD: show less
+
One reason why there is no special attention paid to exception is that at the end, exceptions are just classes. As such the same rules that can be applied to any class that shows up in the API can be applied to exceptions in the API as well. When adding exceptions in your API you will not do anything bad if you follow the ''do not expose more than necessary'' credo of [[Do_Not_Expose_More_Than_You_Want|Chapter 5]]. If your exception is supposed to be thrown just by your code, it is quite OK to make its constructor package private. That will guarantee the intended purpose of the exception, which is, to be thrown only by you and caught by clients of your API. It will guarantee that nobody can misuse and misinterpret this intention. From the opposite point of view: if you want your clients to throw an exception and only your code to consume it, you do not need public getters to get values passed into the constructor at the time the exception is thrown.
 +
 
 +
On the other hand, [[Do_Not_Expose_More_Than_You_Want|Chapter 5]] also advices to prefer factory methods over exposing constructors. I tried that few times, but I have a feeling that this feels a bit unnatural and as such I cannot recommend code like:
 +
 
 +
<source lang="java">
 +
throw CommandException.exitCode(1);
 +
 
 +
 
 +
/** Exception to signal result of execution of external process */
 +
public final class CommandException {
 +
private int exitCode;
 +
 
 +
private CommandException(int e) { exitCode = e; }
 +
 
 +
public static CommandException exitCode(int exitCode) {
 +
return new CommandException(exitcode);
 +
}
 +
}
 +
</source>
 +
 
 +
The common mindshare among Java developers seems to expect that exceptions are raised by writing '''throw new Something''' and it is therefore likely better to expose constructor of your exception class instead of factory method. Still, if you do not expect people to benefit from subclassing your exception, make it '''final''' - your options for [[Ever_Changing_Targets|future evolution]] will remain more open.
 +
 
 +
In short, exceptions are classes. They shall follow the evolution rules applicable to classes, as discussed in [[Code_Against_Interfaces%2C_Not_Implementations|Chapter 6]]. It is not wise to add abstract methods into exceptions could have been subclassed in prior versions, it is not wise to expose fields, remove elements already available, etc. However Casper is right, this is not all that can be said about exceptions, it seems there is something special at the end.
== Runtime vs. Checked ==
== Runtime vs. Checked ==

Revision as of 05:02, 11 September 2008

TBD: just being created as a response to query by Casper Bang:

I was curious as to know how come, in a book strictly about API design in Java, you do not mention exceptions (particular checked exceptions) and the role they play in documenting assertions vs. hampering versionability. Did you simply think this to be too controversial an issue I wonder?

--Casper Bang 05:17, 5 September 2008 (CEST)

Contents

Nothing special

One reason why there is no special attention paid to exception is that at the end, exceptions are just classes. As such the same rules that can be applied to any class that shows up in the API can be applied to exceptions in the API as well. When adding exceptions in your API you will not do anything bad if you follow the do not expose more than necessary credo of Chapter 5. If your exception is supposed to be thrown just by your code, it is quite OK to make its constructor package private. That will guarantee the intended purpose of the exception, which is, to be thrown only by you and caught by clients of your API. It will guarantee that nobody can misuse and misinterpret this intention. From the opposite point of view: if you want your clients to throw an exception and only your code to consume it, you do not need public getters to get values passed into the constructor at the time the exception is thrown.

On the other hand, Chapter 5 also advices to prefer factory methods over exposing constructors. I tried that few times, but I have a feeling that this feels a bit unnatural and as such I cannot recommend code like:

throw CommandException.exitCode(1);
 
 
/** Exception to signal result of execution of external process */
public final class CommandException {
  private int exitCode;
 
  private CommandException(int e) { exitCode = e; }
 
  public static CommandException exitCode(int exitCode) {
    return new CommandException(exitcode);
  }
}

The common mindshare among Java developers seems to expect that exceptions are raised by writing throw new Something and it is therefore likely better to expose constructor of your exception class instead of factory method. Still, if you do not expect people to benefit from subclassing your exception, make it final - your options for future evolution will remain more open.

In short, exceptions are classes. They shall follow the evolution rules applicable to classes, as discussed in Chapter 6. It is not wise to add abstract methods into exceptions could have been subclassed in prior versions, it is not wise to expose fields, remove elements already available, etc. However Casper is right, this is not all that can be said about exceptions, it seems there is something special at the end.

Runtime vs. Checked

TBD: Common flamewar

My Single Exception

TBD: BuildException, maven, I/O

Deciding on Importance

TBD: NetBeans' ErrorManager and Exceptions classes.

Extensibility

TBD: Subclassing. Compare with switch/case

Personal tools
buy