[
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)