[ 
https://issues.apache.org/jira/browse/THRIFT-2908?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14263654#comment-14263654
 ] 

Jens Geyer commented on THRIFT-2908:
------------------------------------

{quote}
{code}
def process_echo(seqid, iprot, oprot)
  args = read_args(iprot, Echo_args)
  result = Echo_result.new()
  result.success = @handler.echo(args.message)
  write_result(result, oprot, 'echo', seqid)
end
{code}

There is no exception handling there. Now if I modify the IDL to throw an 
exception (...) The resulting processor code now includes appropriate rescue 
clauses based off the IDL:

{code}
def process_echo(seqid, iprot, oprot)
  args = read_args(iprot, Echo_args)
  result = Echo_result.new()
  begin
    result.success = @handler.echo(args.message)
  rescue ::EchoException => noEcho
    result.noEcho = noEcho
  end
  write_result(result, oprot, 'echo', seqid)
end
{code}
{quote}

That's right. I simplified my example above but that is more or less the same 
situation. Before that patch, exception handlers were generated only if the IDL 
function declaration had a {{throws}} clause attached. ^1)^ Now, with the patch 
applied, we have two changes:

- Now there is *always* an exception handler generated
- The new handler is added at the end of the list and catches {{Exception}}

The [{{Exception}}|http://docwiki.embarcadero.com/RADStudio/XE/en/Exceptions] 
type is the most generic exception type in Delphi, all other exceptions must 
derive from that one. Putting it at the end of the list ensures, that any of 
the other more specific handlers have a chance to handle the exception. 
However, if nobody else feels responsible, the newly added {{Exception}} 
handler is hit as the handler of last resort. This is even true for {{oneway}} 
calls, except that there is nothing sent back to the client.

{quote}
The client would raise/throw a TApplicationException because the server did not 
return the correct type (NilClass instead of a String). This is the correct and 
expected behaviour based on my reading
{quote}

That's correct, a {{null}} value return is not allowed with Thrift, therefore 
the client raises an {{MissingResult}} ApplicationException because of the 
unexpected state. 

{quote}
It's my understanding that we should be able to wrap all the service handlers 
in something like 

{code}
class Handler
  def echo(string)
    # do something
  rescue => ex
    raise Thrift::ApplicationException.new(Thrift::Application::INTERNAL_ERROR, 
ex.to_s)
  end
end
{code}

Then the thrift library can communicate that failure to the clients and they'll 
receive a {{TApplicationException}} and react accordingly. However this is not 
currently the case. Throwing the {{Thrift::ApplicationException}} or returning 
it has no impact on what the client receives, it receives a 
{{TTransportException}} in both cases. 
{quote}

No, that's not exactly the same. The generated processor code *writes* the 
exception information into the output protocol to be raised on the client side. 
Your code *raises* an exception on the server side. And that may be the cause 
for the {{TTransportException}} that you experience, because nobody catches the 
{{Thrift::ApplicationException}} which very likely leads to the connection 
being terminated unexpectedly.

----
^1)^ ~If you study the changes carefully, you will notice that the generic 
{{Exception}} has also been before, if the compiler option to generate 
additional Thrift Events support code was present. But in that case, after 
notifying the event handler, the exception just caught was raised again to 
bubble up to the next handler. So we can't count that special case.~


> Limited use Thrift::ApplicationException in Ruby
> ------------------------------------------------
>
>                 Key: THRIFT-2908
>                 URL: https://issues.apache.org/jira/browse/THRIFT-2908
>             Project: Thrift
>          Issue Type: Bug
>          Components: Ruby - Library
>    Affects Versions: 0.9.2
>            Reporter: Adam Hawkins
>
> I'm implementing a bunch of Thrift servers in Ruby. I'm trying to figure out 
> how to use {{Thrift::ApplicationException}} for error handling. I came across 
> a link on stack overflow 
> [http://stackoverflow.com/questions/27312244/general-error-handling-in-apache-thrift]
>  that documents exactly what I'm trying to do but applied to the delphi 
> library. The fix (THRIFT-2860) has been merged and set for 0.9.3 release. I'm 
> investigating the generated ruby code and it seems 
> {{Thrift::ApplicationException}} is only used in the clients, and never 
> mentioned in any of the server or processor code. Is it possible to implement 
> a similar fix for ruby severs, or should I define a generic exception and 
> have all RPC's throw that as a work around?



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to