• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Exception handling using socket connection

 
Yanick Labelle
Ranch Hand
Posts: 50
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi, it is my first message on this forum. Sorry for the bad english, we french canadians are not very good at it.
I Have the URLyBird project with version 1.1.1 specified at the top of my instructions.html document. I don't know if it is a NX: projet.
My question was about the casting of an exception received from the server, i'm using socket connections. The server sends a NetworkResponse object to the client. This object encapsulates the response from the server, it can be a record number, a record, a lock cookie, an array of record numbers, or an exception. I've got all of those as instance variables, but only those nessary are initialized. Since I don't know what type of exception the server can possibly return, the encapsulated exception is of type Exception. In my DataNetworkAdapter class which implements the DB interface, I send NetworkRequest(s) to the server and I receive NetworkResponse(s)... In my application, the controler deals with the exceptions, so, my DataNetworkAdapter class neads to get the exception out of the NetworkResponse and rethrow it to the controler (which expects the same behavior from this class as the Data class...). I have found a way to cast the Exception to a more precise type (SecurityException, RecordNotFoundException...) to respect the throws clauses defined in the DB inteface, but I find it rather ugly, I don't think that this is good design... can anyone suggest me anything better than this:
// This is the DataNetworkAdapter class...
// I have one of these methods for each type of exception that I use...
private void checkDuplicateKeyException(NetworkResponse response)
throws DuplicateKeyException
{
if (response.isException() == true
&& response.getException() instanceof DuplicateKeyException)
throw (DuplicateKeyException) response.getException();
}
// this is an example of a calling method...
public String[] read(int recNo)
throws RecordNotFoundException,DataAccessException
{
NetworkRequest request = NetworkRequest.createReadRequest(recNo);
sendRequest(request);
NetworkResponse response = getResponse();
// may throw RecordNotFoundException
checkRecordNotFoundException(response);
// may throw DataAccessException
checkDataAccessException(response);
return response.getRecord();
}
Note: the DataAccessException is a runtime exception... not mentionned in the DB interface. I use it to inform the client of disk or network IOExceptions... Even if it is a runtime exception, i define it in the throw clause of the methods of the classes that implement the DB interface (for clarity). I think that it was my only choice (using a runtime exception) because some method definitions from the DB interface don't even throw exceptions and it becomes hard to return errors to the client.
Also, I don't think that it would be a good idea to mask IOExceptions as RecordNotFoundException or SecurityException...
Please, tell me what you think.
merci!
 
Philippe Maquet
Bartender
Posts: 1872
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi, it is my first message on this forum. Sorry for the bad english, we french canadians are not very good at it.

Salut Yanick ! Pas de probl�me, tu as un Belge en ligne...
Bienvenue sur ce forum !
Ok, back to English now.
I Have the URLyBird project with version 1.1.1 specified at the top of my instructions.html document. I don't know if it is a NX: projet.

It is.
I have found a way to cast the Exception to a more precise type (SecurityException, RecordNotFoundException...) to respect the throws clauses defined in the DB inteface, but I find it rather ugly, I don't think that this is good design... can anyone suggest me anything better than this:

Mmh... Interesting question! I'm not sure my solution is better but it could be handy to have only one generic method to check (and throw) your encapsulated exceptions:

Note: the DataAccessException is a runtime exception... not mentionned in the DB interface. I use it to inform the client of disk or network IOExceptions... Even if it is a runtime exception, i define it in the throw clause of the methods of the classes that implement the DB interface (for clarity). I think that it was my only choice (using a runtime exception) because some method definitions from the DB interface don't even throw exceptions and it becomes hard to return errors to the client.
Also, I don't think that it would be a good idea to mask IOExceptions as RecordNotFoundException or SecurityException...

Perfect!
Regards,
Phil.
 
Yanick Labelle
Ranch Hand
Posts: 50
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Philippe thanks for the quick response (vive les fuseaux horaires differents)!
I am pleased to head from someone who has passed the certification (scjd) that my choice for the runtime exception is a good one.
For my first problem, if the NetworkResponse contains an exception, i need to throw it back to the Controler class. And I can't throw it back as an Exception, because it wouldn't match with what is specified in the DB interface (for example, the read method that I provided can only throw RecordNotFoundException according to interface DB). The problem with the proposed solution is that the exception is never returned to the caller. It is dealed with directly in the DataNetworkAdapter. The controler may want to do usefull things with it, like telling the view to warn the user of what appened.
But maybe I'm wrong with the whole approche... I'm not an experienced Java (or object) developper. In my head, with the MVC approche, The View is the point of communication with the client, requests starts from here and responses end here. The Controler manages the tasks of the client, it contains business methods that the view can call (like searchByCity, ClearSearch, bookRoom etc...). Next, I concider the Data class (or the DataNetworkAdapter class if we are in network mode) as part of the model. they are accessed with very generic (not business) methods like read,update,delete,insert by the business methods of the controler.
My main job as a Synergex developper doesn't allow me to get much experience which that...
If someone could just verify what I just said, it would be nice!
 
Bharat Ruparel
Ranch Hand
Posts: 493
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello Yanick,
Phil is already helping you and his comments are generally to the point. I didn't know how to chain exceptions using the new exception chaining capability of jsdk1.4.XXX. In the following thread Andrew taught me how to do that:
NX: URLy Bird 1.3.1 Explicit Fatal Exception Handling
http://www.coderanch.com/t/184081/java-developer-SCJD/certification/NX-URLy-Bird-Explicit-Fatal
Note that this applies to the runtime exception handling that you are planning on using here.
Good luck and regards.
Bharat
 
Philippe Maquet
Bartender
Posts: 1872
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Yanick,

For my first problem, if the NetworkResponse contains an exception, i need to throw it back to the Controler class. And I can't throw it back as an Exception, because it wouldn't match with what is specified in the DB interface (for example, the read method that I provided can only throw RecordNotFoundException according to interface DB). The problem with the proposed solution is that the exception is never returned to the caller. It is dealed with directly in the DataNetworkAdapter. The controler may want to do usefull things with it, like telling the view to warn the user of what appened.

If your encapsulated exception is a RecordNotFoundException (though referenced as a generic Exception) and you throw it, it's a RecordNotFoundException that will be thrown. No doubt about it:

Now in your checkForExceptions, you can check that the exception stored is an exception you expect by passing an array of exception classes, like I do here:

In someMethod, if response.getException():
  • is null, nothing will happen
  • is an IOException, someMethod() will throw it
  • is any other exception, the catch block in someMethod() will execute with the exception wrapped in an UnexpectedException.


  • Best,
    Phil.
     
    Yanick Labelle
    Ranch Hand
    Posts: 50
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Hi, sorry for the delay, we have a lot of work to do at my job... So I didn't have time to work on my certification...
    But I've resolved my problem by using exception chaining. the server only returns one exception type: AdapterException... which encapsulates an underlying exception...
    I've defined an interface called DataAdapter
    Two classes implements this interface:
    DataNetworkAdapter
    DataLocalAdapter
    The classes that implement these methods are obligated to define those methods:
    public abstract TreeMap find(String[] criteria)
    throws AdapterException;
    public abstract void book(int recNo,String[] record,String custId)
    throws AdapterException;
    those methods are responsible to access the Data class (for the local mode) or the network server (which also uses the DataLocalAdapter to deal which its local data file, if a AdapterException is thrown on the server, it is simply forwarded to the client side)
    Thanks for the support!
     
    Yanick Labelle
    Ranch Hand
    Posts: 50
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    As I think about it, it also resolves one of my other problems. Record deadlocks.
    Before, i had to make all my calls over the network
    lock()
    update()
    unlock()
    So, if the client crashes between the lock call and the unlock call, the record is locked forever. I made a thread that runs on the server, which checks every minutes for locks that are more than one minute old... and removes them.
    Now, the only call that has to travel over the network is
    book()
    The server will then call those 3 methods...
    lock()
    update()
    unlock()
    So with this solution, the deadlock problem doesn't exist.
    Just some reflections... It seams ok, but i'm not a java expert. If anyone thinks that what I just said doesn't make sense, please tell me!
     
    • Post Reply
    • Bookmark Topic Watch Topic
    • New Topic