I'm just finishing project and have many doubts about my approach to throwing exceptions
from class implementing delivered interface for accessing data base file.
In my opinion methods in delivered interface suncertify.db.DBAccess are only allowed
to throw limited number of exception which are not covering all possible
problems which might occur while managing database/locking process.
To resolve this problem there are 2 possible approaches [I’ve choose (a)]
a) wrapping caught exceptions in exceptions included in interface and rethrowing them
Because of this limitation I'm throwing only allowed exception to inform also about errors
which not fully adhere to names and purposes described in instruction for these exceptions.
So if anything in method will go wrong and it was not expected (not included in interface
method description) then I'm using allowed exception and setting exception message
describing the problem.
b) wrapping caught exceptions in new exception extending RuntimeException and throwing this one
This approach is based on adding new exception extending RuntimeException to inform about situations not included in interface. But it can be confusing for other developers, because according to provided interface methods can't throw this type of exception (developer will be not obligated to catch them in his code). To inform about this possibility
I could add in javadoc comment this information. But as I wrote I choose first approach.
Could you tell me which approach is more appropriate?
According to delivered interface method “unlock” can throw only one exception SecurityException, and have two parameters: record number and cookie.
If cookie is not equal to cookie which was used to lock this record then it throw
SecurityException, that’s fine but what if record number is not correct (for example
<0 or not in database)?
According to above approaches if record number is invalid:
a) throw allowed exception with description of the problem:
new SecurityException("Record number is invalid")
I choose this approach.
b) create new exception extending RuntimeException for example RecordNumberInvalid and
throw this one.
Hello there. Nice to hear that you are almost done. About throwing exceptions for SCJD, any exceptions thrown in the Data class will ultimately seen on the server side. So depending on your architecture setup, you may have an exception that wraps the Sun's provided exceptions and throw that exception in your local/remote interface for the client. Ultimately the client code should need to worry 2 exceptions - one database and one server exception (eg if using RMI RemoteException will be your server exception).
So given your current approach (a) is the correct approach. Now talking when to throw such exceptions in your local/remote interfaces seems to your concern. Given any write operations you need to explicitly call lock/unlock (eg lock -> update -> unlock). Not knowing your lock/unlock method signature, all error checking (eg valid record number, valid cookie, etc) should all be done in the lock method. The update/delete methods should just modify the data. The unlock method should just have notifyAll() - no need to throw any exceptions (like in your example). Hope this helps.
I mightn't expressed myself correctly, maybe better if I will give some simple example.
Method readRecord(recordNumber) according to interface can throw exception RecordNotFoundException (checked exception) in case if record doesn't exist in database or is market as deleted.
That's fine but in process of reading data from database some unexpected error can occur - for example data format was incorrect, data length is wrong etc.
In this situation I have 2 options:
1) use allowed RecordNotFoundException with constructor containing parameter "String message" and set it to something descriptive like: "Unexpected error while reading record numer N".
2) add unchecked exception to my implementation of this method, for example MalformedRecordException ant throw it
My choice was 1) because in this case I've guarantee that other developer who might use my implementation will have to catch it, while 2) is no guaranteeing this. But according to my instruction I should throw RecordNotFoundException if record is missing or is marked as deleted.
I'm not sure if I've choose right option - hope you will share you ideas related with this problem
...but in process of reading data from database some unexpected error can occur - for example data format was incorrect, data length is wrong etc.
Champion, this isn't really supposed to happen. You have to verify if the database is valid when starting the application (you may assume that if the magic cookie is valid, then the file being used is valid - and do not forget to include this in your choices.txt file); if so, then this shouldn't happen. Any other checked exception that may occur in the run (such as IOException) that is not in the class' API can be wrapped in an unchecked exception (such as RuntimeException).