RE: Please Don't Eat Exceptions

2007-06-03 Thread Jerome Louvel

Hi Adam,

Thanks for pointing me to your patches. I've just reviewed them. 

For the first one on HttpMethodCall, the fact that there is no body doesn't
indicate an error, it can be the expected result for a HEAD request or a 304
status. I don't think that throwing a RuntimeException is necessary. Could
you explain why you needed this?

For the patch on HttpClientHelper, I agree that the getConverter() method
shouldn't eat all those exceptions. Now, the method declares a throws
Exception, and the handle() method catch them and set the status to
CONNECTOR_INTERNAL_ERROR (as discussed before). I hope this will satisfy
you. Otherwise, let us know or reopen the bug report.

Best regards,
Jerome  

 -Message d'origine-
 De : Adam Taft [mailto:[EMAIL PROTECTED] 
 Envoyé : dimanche 3 juin 2007 04:10
 À : discuss@restlet.tigris.org
 Objet : Re: Please Don't Eat Exceptions
 
 Jerome,
 
 I think I had to patch the code in two places to get it to 
 work.  There 
 was another instance of this type of code in HttpMethodCall.  
 You might 
 want to look for it there (or look at my patch in the bug 
 report, which 
 should give you an idea of where to look).
 
 Thanks,
 
 Adam
 
 
 Jerome Louvel wrote:
  Hi Adam,
  
  The fix I've just checked in SVN should solve your issue. 
 You now can check
  whether your request generated an error by solely looking 
 at the response's
  status code. In your case, it would return a 
 CONNECTOR_ERROR_INTERNAL
  because we don't fully deal with invalid URIs. In the 
 future, we might
  improve the precision of the status. In your case you could 
 also expect a
  CLIENT_ERROR_BAD_REQUEST because:
   - you provided a non HTTP URI (a)
   - you didn't provide a Request's hostRef property to 
 indicate the host to
  connect to
  
  I understand your preference for checked exceptions. For a 
 Java-centric API
  I would design like you propose, but for a REST/HTTP API, I 
 think it's
  better and more consistent to reuse and extend the HTTP 
 status mechanism.
  
  Best regards,
  Jerome  
  
  -Message d'origine-
  De : Adam Taft [mailto:[EMAIL PROTECTED] 
  Envoyé : vendredi 1 juin 2007 06:05
  À : discuss@restlet.tigris.org
  Objet : Re: Please Don't Eat Exceptions
 
 
  I don't necessarily understand where the first stage and 
  the second 
  stage are in the code you're referring to.  So, I can't 
 guess as to 
  whether it's a good solution.
 
  Maybe think about a lower level functional class (ie. 
  basically what is 
  Client right now) throwing checked exceptions out of the 
  handle method. 
And then, having a convenience class that extends Client 
  and wraps 
  the exceptions to produce an appropriate error Status code.  
  This would 
  allow the best of both worlds, by allowing the checked 
  exceptions to be 
  dealt with programatically by the end user/developer, while also 
  allowing a non-checked configuration for those who want it.
 
  A developer who wants the checked exceptions would do:
 
  Client client = new Client();
 
  A developer who wants to do if-then-else testing on the 
 status code 
  would do:
 
  UncheckedClient client = new UncheckedClient();
 
  Where UncheckedClient extends Client.
 
  Regardless, down in the depths of the specification, it's 
 in my mind 
  that the handle method should throw exceptions.
 
  Just some additional thoughts, I guess.
 
  Adam
 
 
  Thierry Boileau wrote:
  Hello,
 
  we had a discussion with Jerome, and we plainly agree 
 with the fact 
  there is a problem in HttpClientHelper#handle [1] method as 
  pointed out 
  thanksfully by Adam and Jim.
  This method first builds a call object then sends this call 
  and gets the 
  server's response.
  The try/catch block is very problematic in the case the 
  build step of 
  the call fails. We've decided to remove it.
  That is to say that all errors detected in this first step 
  will be in 
  charge of the caller code which is responsible to give 
  correct data.
  A contrario, the errors detected in the second phase should 
  generate a 
  status code:
  - Status.CONNECTOR_ERROR_XXX (where XXX stands for CONNECTION, 
  COMMUNICATION and INTERNAL) for all errors detected before 
  the request 
  is sent. This is the current behaviour.
  - HTTP status received from the server.
 
 
  What do you think about?
 
  best regards,
  Thierry Boileau
  [1]
 public void handle(Request request, Response response) {
 try {
 HttpClientCall httpCall = 
  getConverter().toSpecific(this, 
  request);
 getConverter().commit(httpCall, request, response);
 } catch (Exception e) {
 getLogger().log(Level.WARNING,
 Error while handling an HTTP client call: ,
 e.getMessage());
 getLogger().log(Level.INFO,
 Error while handling an HTTP client call, e);
 }
 }
 
 
  I made some comments to the bug, by the way.
 
  One thing

Re: Please Don't Eat Exceptions

2007-06-03 Thread Adam Taft

Jerome,

I just know I had to track it down to two places when performing the 
test case I presented.  I'll check out the new change to 
HttpClientHelper and see if that works for me.  It could be that I was 
seeing a ghost.  ;)


Anyway, no problem.  I'll reopen the bug if there are additional issues.

Adam


Jerome Louvel wrote:

Hi Adam,

Thanks for pointing me to your patches. I've just reviewed them. 


For the first one on HttpMethodCall, the fact that there is no body doesn't
indicate an error, it can be the expected result for a HEAD request or a 304
status. I don't think that throwing a RuntimeException is necessary. Could
you explain why you needed this?

For the patch on HttpClientHelper, I agree that the getConverter() method
shouldn't eat all those exceptions. Now, the method declares a throws
Exception, and the handle() method catch them and set the status to
CONNECTOR_INTERNAL_ERROR (as discussed before). I hope this will satisfy
you. Otherwise, let us know or reopen the bug report.

Best regards,
Jerome  


-Message d'origine-
De : Adam Taft [mailto:[EMAIL PROTECTED] 
Envoyé : dimanche 3 juin 2007 04:10

À : discuss@restlet.tigris.org
Objet : Re: Please Don't Eat Exceptions

Jerome,

I think I had to patch the code in two places to get it to 
work.  There 
was another instance of this type of code in HttpMethodCall.  
You might 
want to look for it there (or look at my patch in the bug 
report, which 
should give you an idea of where to look).


Thanks,

Adam


Jerome Louvel wrote:

Hi Adam,

The fix I've just checked in SVN should solve your issue. 

You now can check
whether your request generated an error by solely looking 

at the response's
status code. In your case, it would return a 

CONNECTOR_ERROR_INTERNAL
because we don't fully deal with invalid URIs. In the 

future, we might
improve the precision of the status. In your case you could 

also expect a

CLIENT_ERROR_BAD_REQUEST because:
 - you provided a non HTTP URI (a)
 - you didn't provide a Request's hostRef property to 

indicate the host to

connect to

I understand your preference for checked exceptions. For a 

Java-centric API
I would design like you propose, but for a REST/HTTP API, I 

think it's
better and more consistent to reuse and extend the HTTP 

status mechanism.

Best regards,
Jerome  


-Message d'origine-
De : Adam Taft [mailto:[EMAIL PROTECTED] 
Envoyé : vendredi 1 juin 2007 06:05

À : discuss@restlet.tigris.org
Objet : Re: Please Don't Eat Exceptions


I don't necessarily understand where the first stage and 
the second 
stage are in the code you're referring to.  So, I can't 
guess as to 

whether it's a good solution.

Maybe think about a lower level functional class (ie. 
basically what is 
Client right now) throwing checked exceptions out of the 
handle method. 
  And then, having a convenience class that extends Client 
and wraps 
the exceptions to produce an appropriate error Status code.  
This would 
allow the best of both worlds, by allowing the checked 
exceptions to be 
dealt with programatically by the end user/developer, while also 
allowing a non-checked configuration for those who want it.


A developer who wants the checked exceptions would do:

Client client = new Client();

A developer who wants to do if-then-else testing on the 
status code 

would do:

UncheckedClient client = new UncheckedClient();

Where UncheckedClient extends Client.

Regardless, down in the depths of the specification, it's 
in my mind 

that the handle method should throw exceptions.

Just some additional thoughts, I guess.

Adam


Thierry Boileau wrote:

Hello,

we had a discussion with Jerome, and we plainly agree 
with the fact 
there is a problem in HttpClientHelper#handle [1] method as 
pointed out 

thanksfully by Adam and Jim.
This method first builds a call object then sends this call 
and gets the 

server's response.
The try/catch block is very problematic in the case the 
build step of 

the call fails. We've decided to remove it.
That is to say that all errors detected in this first step 
will be in 
charge of the caller code which is responsible to give 

correct data.
A contrario, the errors detected in the second phase should 
generate a 

status code:
- Status.CONNECTOR_ERROR_XXX (where XXX stands for CONNECTION, 
COMMUNICATION and INTERNAL) for all errors detected before 
the request 

is sent. This is the current behaviour.
- HTTP status received from the server.


What do you think about?

best regards,
Thierry Boileau
[1]
   public void handle(Request request, Response response) {
   try {
   HttpClientCall httpCall = 
getConverter().toSpecific(this, 

request);
   getConverter().commit(httpCall, request, response);
   } catch (Exception e) {
   getLogger().log(Level.WARNING,
   Error while handling an HTTP client call: ,
   e.getMessage());
   getLogger().log(Level.INFO

RE: Please Don't Eat Exceptions

2007-06-02 Thread Jerome Louvel

Hi Adam,

The fix I've just checked in SVN should solve your issue. You now can check
whether your request generated an error by solely looking at the response's
status code. In your case, it would return a CONNECTOR_ERROR_INTERNAL
because we don't fully deal with invalid URIs. In the future, we might
improve the precision of the status. In your case you could also expect a
CLIENT_ERROR_BAD_REQUEST because:
 - you provided a non HTTP URI (a)
 - you didn't provide a Request's hostRef property to indicate the host to
connect to

I understand your preference for checked exceptions. For a Java-centric API
I would design like you propose, but for a REST/HTTP API, I think it's
better and more consistent to reuse and extend the HTTP status mechanism.

Best regards,
Jerome  

 -Message d'origine-
 De : Adam Taft [mailto:[EMAIL PROTECTED] 
 Envoyé : vendredi 1 juin 2007 06:05
 À : discuss@restlet.tigris.org
 Objet : Re: Please Don't Eat Exceptions
 
 
 I don't necessarily understand where the first stage and 
 the second 
 stage are in the code you're referring to.  So, I can't guess as to 
 whether it's a good solution.
 
 Maybe think about a lower level functional class (ie. 
 basically what is 
 Client right now) throwing checked exceptions out of the 
 handle method. 
   And then, having a convenience class that extends Client 
 and wraps 
 the exceptions to produce an appropriate error Status code.  
 This would 
 allow the best of both worlds, by allowing the checked 
 exceptions to be 
 dealt with programatically by the end user/developer, while also 
 allowing a non-checked configuration for those who want it.
 
 A developer who wants the checked exceptions would do:
 
 Client client = new Client();
 
 A developer who wants to do if-then-else testing on the status code 
 would do:
 
 UncheckedClient client = new UncheckedClient();
 
 Where UncheckedClient extends Client.
 
 Regardless, down in the depths of the specification, it's in my mind 
 that the handle method should throw exceptions.
 
 Just some additional thoughts, I guess.
 
 Adam
 
 
 Thierry Boileau wrote:
  Hello,
  
  we had a discussion with Jerome, and we plainly agree with the fact 
  there is a problem in HttpClientHelper#handle [1] method as 
 pointed out 
  thanksfully by Adam and Jim.
  This method first builds a call object then sends this call 
 and gets the 
  server's response.
  The try/catch block is very problematic in the case the 
 build step of 
  the call fails. We've decided to remove it.
  That is to say that all errors detected in this first step 
 will be in 
  charge of the caller code which is responsible to give 
 correct data.
  
  A contrario, the errors detected in the second phase should 
 generate a 
  status code:
  - Status.CONNECTOR_ERROR_XXX (where XXX stands for CONNECTION, 
  COMMUNICATION and INTERNAL) for all errors detected before 
 the request 
  is sent. This is the current behaviour.
  - HTTP status received from the server.
  
  
  What do you think about?
  
  best regards,
  Thierry Boileau
  [1]
 public void handle(Request request, Response response) {
 try {
 HttpClientCall httpCall = 
 getConverter().toSpecific(this, 
  request);
 getConverter().commit(httpCall, request, response);
 } catch (Exception e) {
 getLogger().log(Level.WARNING,
 Error while handling an HTTP client call: ,
 e.getMessage());
 getLogger().log(Level.INFO,
 Error while handling an HTTP client call, e);
 }
 }
  
  
 
  I made some comments to the bug, by the way.
 
  One thing that came to mind, about handling different 3rd 
 party client 
  apis, is to deal with it like Spring deals with JDBC 
 exceptions.  In 
  essence, they wrap and catch the various jdbc/driver 
 exceptions and 
  then map it to a set of common spring defined exceptions.
 
  In my mind, the Status code in the Response object should 
 be a direct 
  mapping to the HTTP status codes.  This is really the 
 intent you guys 
  had.  Of course, the status code is undefined for a request that 
  cannot establish a connection with the host, due to 
 various problems 
  (physical connection, dns, proxy related issues, no route 
 to host, etc.)
 
  Without the ability to detect these kind of connectivity 
 issues in 
  developer code, the Client class is pretty worthless.  Having a 
  generic isError() method or a bogus status code in the response 
  doesn't give the level of detail needed.
 
  You're also forcing developers to use the nasty pattern of 
 switch or 
  if/else statements to check for the appropriate conditions in the 
  Response object.  If I'm making multiple requests to the 
 server (which 
  is common in a RESTful design), and the first call results 
 in a 404 
  Not Found, I don't want to have to keep checking under 
 each statement 
  for the various status codes.  I just want

Re: Please Don't Eat Exceptions

2007-05-31 Thread Stian Soiland


On 30 May 2007, at 22:56, Jim Alateras wrote:


I'm fine with the design choice. I stumbled across a place where  
this wasn't happening [1] but it was hard to associate a HTTP  
status code with the failure since the request failed to leave the  
client. Currently I have patched it to set the following status code


response.setStatus(Status.CLIENT_ERROR_NOT_FOUND);


You can't use 404 for this, a typical REST application could PUT  
something after the 404. Also then there would be no way to see if it  
was a real 404.


I think wrong hostname (or network connectivity problems) means an  
IOException should be thrown, just like when trying to do getEntity 
().getText(). After all, we are still talking about the internet, and  
a number of different connectivity issues could occur that can't be  
described using HTTP status codes.


--
Stian Soiland, myGrid team
School of Computer Science
The University of Manchester
http://www.cs.man.ac.uk/~ssoiland/



Re: Please Don't Eat Exceptions

2007-05-31 Thread Thierry Boileau

Hello,

we had a discussion with Jerome, and we plainly agree with the fact 
there is a problem in HttpClientHelper#handle [1] method as pointed out 
thanksfully by Adam and Jim.
This method first builds a call object then sends this call and gets the 
server's response.
The try/catch block is very problematic in the case the build step of 
the call fails. We've decided to remove it.
That is to say that all errors detected in this first step will be in 
charge of the caller code which is responsible to give correct data.


A contrario, the errors detected in the second phase should generate a 
status code:
- Status.CONNECTOR_ERROR_XXX (where XXX stands for CONNECTION, 
COMMUNICATION and INTERNAL) for all errors detected before the request 
is sent. This is the current behaviour.

- HTTP status received from the server.


What do you think about?

best regards,
Thierry Boileau
[1]
   public void handle(Request request, Response response) {
   try {
   HttpClientCall httpCall = getConverter().toSpecific(this, 
request);

   getConverter().commit(httpCall, request, response);
   } catch (Exception e) {
   getLogger().log(Level.WARNING,
   Error while handling an HTTP client call: ,
   e.getMessage());
   getLogger().log(Level.INFO,
   Error while handling an HTTP client call, e);
   }
   }




I made some comments to the bug, by the way.

One thing that came to mind, about handling different 3rd party client 
apis, is to deal with it like Spring deals with JDBC exceptions.  In 
essence, they wrap and catch the various jdbc/driver exceptions and 
then map it to a set of common spring defined exceptions.


In my mind, the Status code in the Response object should be a direct 
mapping to the HTTP status codes.  This is really the intent you guys 
had.  Of course, the status code is undefined for a request that 
cannot establish a connection with the host, due to various problems 
(physical connection, dns, proxy related issues, no route to host, etc.)


Without the ability to detect these kind of connectivity issues in 
developer code, the Client class is pretty worthless.  Having a 
generic isError() method or a bogus status code in the response 
doesn't give the level of detail needed.


You're also forcing developers to use the nasty pattern of switch or 
if/else statements to check for the appropriate conditions in the 
Response object.  If I'm making multiple requests to the server (which 
is common in a RESTful design), and the first call results in a 404 
Not Found, I don't want to have to keep checking under each statement 
for the various status codes.  I just want to have the requests one 
per line and get an exception thrown for problems.


This is why I mentioned, in the bug, about the wrapper I use that 
throws a UnexpectedStatusException (a custom exception class).  The 
use of the code looks like this:


try {
  Client client = new Client(...);
  client.handle(request1, response1, Status.SUCCESS_OK);
  client.handle(request2, response2, Status.SUCCESS_OK);

} catch (IOException e) {
  // something bad has happened
  // like no connection, host name dns failure, etc.

} catch (UnexpectedStatusException e) {
  // this is where you can put your if/then checking
  if (e.getStatus().equals(Status.CLIENT_ERROR_NOT_FOUND)) {
// 404 Not Found message to user
return;
  }

  // other handling here, or just some generic handling code

}

Note the additional parameter for the expected status in the 
handle() method.


Anyway, the point is, you could in theory force all the client related 
exceptions into either IOException or UnexpectedStatusException.  
Then, you'd have a consistent API for dealing with both HTTP status 
code related issues as well as the other connectivity problems related 
to the physical connection.  Defining handle() to throw both of these 
is, in my mind, the right direction.


Adam


Thierry Boileau wrote:

Adam,

I just want to explain why this behaviour happens, not to plainly 
justify it.
As you point, it has been decided to show the failures by the way of 
the status code and not by the way of the exceptions.
One reason is that for example, the connectors are based on other 
externals projects that may throw exceptions of different nature even 
for equivalent issues, and the connectors may throw themselves 
distinct exceptions for equivalent issues (equivalent from the API's 
point of view).
Then, it has seemed difficult to potentially have to catch a growing 
list of distinct exceptions in some part of the code (not the whole 
code, of course). Thus, it has been decided, and it's a design 
choice, to use the status codes instead of the exceptions.

However, this behaviour may be updated, the discussion is open.

best regards,
Thierry Boileau


Oops, didn't see your reply here.  I just replied to your other thread.

Actually, I disagree.  I think the problem is that the method 

Re: Please Don't Eat Exceptions

2007-05-31 Thread Jim Alateras

works for me. Will you create an issue for this.

cheers
/jima
Thierry Boileau wrote:

Hello,

we had a discussion with Jerome, and we plainly agree with the fact 
there is a problem in HttpClientHelper#handle [1] method as pointed out 
thanksfully by Adam and Jim.
This method first builds a call object then sends this call and gets the 
server's response.
The try/catch block is very problematic in the case the build step of 
the call fails. We've decided to remove it.
That is to say that all errors detected in this first step will be in 
charge of the caller code which is responsible to give correct data.


A contrario, the errors detected in the second phase should generate a 
status code:
- Status.CONNECTOR_ERROR_XXX (where XXX stands for CONNECTION, 
COMMUNICATION and INTERNAL) for all errors detected before the request 
is sent. This is the current behaviour.

- HTTP status received from the server.


What do you think about?

best regards,
Thierry Boileau
[1]
   public void handle(Request request, Response response) {
   try {
   HttpClientCall httpCall = getConverter().toSpecific(this, 
request);

   getConverter().commit(httpCall, request, response);
   } catch (Exception e) {
   getLogger().log(Level.WARNING,
   Error while handling an HTTP client call: ,
   e.getMessage());
   getLogger().log(Level.INFO,
   Error while handling an HTTP client call, e);
   }
   }




I made some comments to the bug, by the way.

One thing that came to mind, about handling different 3rd party client 
apis, is to deal with it like Spring deals with JDBC exceptions.  In 
essence, they wrap and catch the various jdbc/driver exceptions and 
then map it to a set of common spring defined exceptions.


In my mind, the Status code in the Response object should be a direct 
mapping to the HTTP status codes.  This is really the intent you guys 
had.  Of course, the status code is undefined for a request that 
cannot establish a connection with the host, due to various problems 
(physical connection, dns, proxy related issues, no route to host, etc.)


Without the ability to detect these kind of connectivity issues in 
developer code, the Client class is pretty worthless.  Having a 
generic isError() method or a bogus status code in the response 
doesn't give the level of detail needed.


You're also forcing developers to use the nasty pattern of switch or 
if/else statements to check for the appropriate conditions in the 
Response object.  If I'm making multiple requests to the server (which 
is common in a RESTful design), and the first call results in a 404 
Not Found, I don't want to have to keep checking under each statement 
for the various status codes.  I just want to have the requests one 
per line and get an exception thrown for problems.


This is why I mentioned, in the bug, about the wrapper I use that 
throws a UnexpectedStatusException (a custom exception class).  The 
use of the code looks like this:


try {
  Client client = new Client(...);
  client.handle(request1, response1, Status.SUCCESS_OK);
  client.handle(request2, response2, Status.SUCCESS_OK);

} catch (IOException e) {
  // something bad has happened
  // like no connection, host name dns failure, etc.

} catch (UnexpectedStatusException e) {
  // this is where you can put your if/then checking
  if (e.getStatus().equals(Status.CLIENT_ERROR_NOT_FOUND)) {
// 404 Not Found message to user
return;
  }

  // other handling here, or just some generic handling code

}

Note the additional parameter for the expected status in the 
handle() method.


Anyway, the point is, you could in theory force all the client related 
exceptions into either IOException or UnexpectedStatusException.  
Then, you'd have a consistent API for dealing with both HTTP status 
code related issues as well as the other connectivity problems related 
to the physical connection.  Defining handle() to throw both of these 
is, in my mind, the right direction.


Adam


Thierry Boileau wrote:

Adam,

I just want to explain why this behaviour happens, not to plainly 
justify it.
As you point, it has been decided to show the failures by the way of 
the status code and not by the way of the exceptions.
One reason is that for example, the connectors are based on other 
externals projects that may throw exceptions of different nature even 
for equivalent issues, and the connectors may throw themselves 
distinct exceptions for equivalent issues (equivalent from the API's 
point of view).
Then, it has seemed difficult to potentially have to catch a growing 
list of distinct exceptions in some part of the code (not the whole 
code, of course). Thus, it has been decided, and it's a design 
choice, to use the status codes instead of the exceptions.

However, this behaviour may be updated, the discussion is open.

best regards,
Thierry Boileau


Oops, didn't see your reply here.  I just replied to 

Re: Please Don't Eat Exceptions

2007-05-31 Thread Adam Taft


I don't necessarily understand where the first stage and the second 
stage are in the code you're referring to.  So, I can't guess as to 
whether it's a good solution.


Maybe think about a lower level functional class (ie. basically what is 
Client right now) throwing checked exceptions out of the handle method. 
 And then, having a convenience class that extends Client and wraps 
the exceptions to produce an appropriate error Status code.  This would 
allow the best of both worlds, by allowing the checked exceptions to be 
dealt with programatically by the end user/developer, while also 
allowing a non-checked configuration for those who want it.


A developer who wants the checked exceptions would do:

Client client = new Client();

A developer who wants to do if-then-else testing on the status code 
would do:


UncheckedClient client = new UncheckedClient();

Where UncheckedClient extends Client.

Regardless, down in the depths of the specification, it's in my mind 
that the handle method should throw exceptions.


Just some additional thoughts, I guess.

Adam


Thierry Boileau wrote:

Hello,

we had a discussion with Jerome, and we plainly agree with the fact 
there is a problem in HttpClientHelper#handle [1] method as pointed out 
thanksfully by Adam and Jim.
This method first builds a call object then sends this call and gets the 
server's response.
The try/catch block is very problematic in the case the build step of 
the call fails. We've decided to remove it.
That is to say that all errors detected in this first step will be in 
charge of the caller code which is responsible to give correct data.


A contrario, the errors detected in the second phase should generate a 
status code:
- Status.CONNECTOR_ERROR_XXX (where XXX stands for CONNECTION, 
COMMUNICATION and INTERNAL) for all errors detected before the request 
is sent. This is the current behaviour.

- HTTP status received from the server.


What do you think about?

best regards,
Thierry Boileau
[1]
   public void handle(Request request, Response response) {
   try {
   HttpClientCall httpCall = getConverter().toSpecific(this, 
request);

   getConverter().commit(httpCall, request, response);
   } catch (Exception e) {
   getLogger().log(Level.WARNING,
   Error while handling an HTTP client call: ,
   e.getMessage());
   getLogger().log(Level.INFO,
   Error while handling an HTTP client call, e);
   }
   }




I made some comments to the bug, by the way.

One thing that came to mind, about handling different 3rd party client 
apis, is to deal with it like Spring deals with JDBC exceptions.  In 
essence, they wrap and catch the various jdbc/driver exceptions and 
then map it to a set of common spring defined exceptions.


In my mind, the Status code in the Response object should be a direct 
mapping to the HTTP status codes.  This is really the intent you guys 
had.  Of course, the status code is undefined for a request that 
cannot establish a connection with the host, due to various problems 
(physical connection, dns, proxy related issues, no route to host, etc.)


Without the ability to detect these kind of connectivity issues in 
developer code, the Client class is pretty worthless.  Having a 
generic isError() method or a bogus status code in the response 
doesn't give the level of detail needed.


You're also forcing developers to use the nasty pattern of switch or 
if/else statements to check for the appropriate conditions in the 
Response object.  If I'm making multiple requests to the server (which 
is common in a RESTful design), and the first call results in a 404 
Not Found, I don't want to have to keep checking under each statement 
for the various status codes.  I just want to have the requests one 
per line and get an exception thrown for problems.


This is why I mentioned, in the bug, about the wrapper I use that 
throws a UnexpectedStatusException (a custom exception class).  The 
use of the code looks like this:


try {
  Client client = new Client(...);
  client.handle(request1, response1, Status.SUCCESS_OK);
  client.handle(request2, response2, Status.SUCCESS_OK);

} catch (IOException e) {
  // something bad has happened
  // like no connection, host name dns failure, etc.

} catch (UnexpectedStatusException e) {
  // this is where you can put your if/then checking
  if (e.getStatus().equals(Status.CLIENT_ERROR_NOT_FOUND)) {
// 404 Not Found message to user
return;
  }

  // other handling here, or just some generic handling code

}

Note the additional parameter for the expected status in the 
handle() method.


Anyway, the point is, you could in theory force all the client related 
exceptions into either IOException or UnexpectedStatusException.  
Then, you'd have a consistent API for dealing with both HTTP status 
code related issues as well as the other connectivity problems related 
to the physical connection.  

Re: Please Don't Eat Exceptions

2007-05-30 Thread Jim Alateras

Thierry,

I'm fine with the design choice. I stumbled across a place where this 
wasn't happening [1] but it was hard to associate a HTTP status code 
with the failure since the request failed to leave the client. 
Currently I have patched it to set the following status code


response.setStatus(Status.CLIENT_ERROR_NOT_FOUND);

Any thoughts?


[1] http://restlet.tigris.org/servlets/ReadMsg?list=discussmsgNo=2176


Thierry Boileau wrote:

Adam,

I just want to explain why this behaviour happens, not to plainly 
justify it.
As you point, it has been decided to show the failures by the way of the 
status code and not by the way of the exceptions.
One reason is that for example, the connectors are based on other 
externals projects that may throw exceptions of different nature even 
for equivalent issues, and the connectors may throw themselves distinct 
exceptions for equivalent issues (equivalent from the API's point of view).
Then, it has seemed difficult to potentially have to catch a growing 
list of distinct exceptions in some part of the code (not the whole 
code, of course). Thus, it has been decided, and it's a design choice, 
to use the status codes instead of the exceptions.

However, this behaviour may be updated, the discussion is open.

best regards,
Thierry Boileau


Oops, didn't see your reply here.  I just replied to your other thread.

Actually, I disagree.  I think the problem is that the method should
have originally been defined to through checked exceptions.

I want to be to notify the user of the exceptions inside of the client
itself.  If my end user has entered a bad url, then I want to be able to
notify them about that, for example.

Setting a status code is not the way to handle this.  You propose status
code 404, but that's not an appropriate response for a host not found
type of problem.  Likewise, it's also not an appropriate status code if
the url itself was poorly formed (like, without a leading protocol 
scheme).


Anyway, my point is, there are many reason which a request could fail.
I want to see these in my own code so that I can do what's appropriate
with the exception.

Adam


Jim Alateras wrote:

Adam,

I came across the same problem and I believe the problem is more 
around not setting the response status code on failure.


cheers
/jima

Adam Taft wrote:


Here's a test case to look at...

public class TestClass {
public static void main(String[] args) {
   try {
Request request = new Request(Method.GET, 
a);

Client client = new Client(Protocol.HTTP);
client.handle(request);
   System.out.println(This code shouldn't run!);
   } catch (Throwable t) {
// eat everything
}
   }
}

The offending code is in HttpClientHelper#handle ...

public void handle(Request request, Response response) {
try {
HttpClientCall httpCall = 
getConverter().toSpecific(this, request);

getConverter().commit(httpCall, request, response);
} catch (Exception e) {
getLogger().log(Level.WARNING,
Error while handling an HTTP client call: ,
e.getMessage());
getLogger().log(Level.INFO,
Error while handling an HTTP client call, e);
}
}


As soon as I get my email confirmation from tigris, I'll file a bug 
report.  I just wanted to mention this in case there are other areas 
you know about with similar code.  If the goal is to log the 
exception, that's ok, but it needs to be re-thrown.


Thanks!

Adam







Re: Please Don't Eat Exceptions

2007-05-28 Thread Jim Alateras

Adam,

I came across the same problem and I believe the problem is more around 
not setting the response status code on failure.


cheers
/jima

Adam Taft wrote:


Here's a test case to look at...

public class TestClass {

public static void main(String[] args) {
   
try {

Request request = new Request(Method.GET, a);
Client client = new Client(Protocol.HTTP);
client.handle(request);
   
System.out.println(This code shouldn't run!);
   
} catch (Throwable t) {

// eat everything
}
   
}

}

The offending code is in HttpClientHelper#handle ...

public void handle(Request request, Response response) {
try {
HttpClientCall httpCall = getConverter().toSpecific(this, 
request);

getConverter().commit(httpCall, request, response);
} catch (Exception e) {
getLogger().log(Level.WARNING,
Error while handling an HTTP client call: ,
e.getMessage());
getLogger().log(Level.INFO,
Error while handling an HTTP client call, e);
}
}


As soon as I get my email confirmation from tigris, I'll file a bug 
report.  I just wanted to mention this in case there are other areas you 
know about with similar code.  If the goal is to log the exception, 
that's ok, but it needs to be re-thrown.


Thanks!

Adam



Please Don't Eat Exceptions

2007-05-23 Thread Adam Taft


Here's a test case to look at...

public class TestClass {

public static void main(String[] args) {

try {
Request request = new Request(Method.GET, 
a);
Client client = new Client(Protocol.HTTP);
client.handle(request);

System.out.println(This code shouldn't run!);

} catch (Throwable t) {
// eat everything
}

}
}

The offending code is in HttpClientHelper#handle ...

public void handle(Request request, Response response) {
try {
HttpClientCall httpCall = getConverter().toSpecific(this, 
request);

getConverter().commit(httpCall, request, response);
} catch (Exception e) {
getLogger().log(Level.WARNING,
Error while handling an HTTP client call: ,
e.getMessage());
getLogger().log(Level.INFO,
Error while handling an HTTP client call, e);
}
}


As soon as I get my email confirmation from tigris, I'll file a bug 
report.  I just wanted to mention this in case there are other areas you 
know about with similar code.  If the goal is to log the exception, 
that's ok, but it needs to be re-thrown.


Thanks!

Adam