[ https://issues.apache.org/jira/browse/THRIFT-2908?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14254917#comment-14254917 ]
Adam Hawkins commented on THRIFT-2908: -------------------------------------- Thanks for the quick response. I've prepared some small code examples to make sure you and I are communicating correctly. Here's an example Thrift IDL file. {code:title=echo_service.thrift} service EchoService { string echo(1: string message) void explode() } {code} Here's a snippet from the generated {{echo_service.thrift}} file. {code:title=echo_service.rb} class Processor include ::Thrift::Processor 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 def process_explode(seqid, iprot, oprot) args = read_args(iprot, Explode_args) result = Explode_result.new() @handler.explode() write_result(result, oprot, 'explode', seqid) end end {code} There is no exception handling there. Now if I modify the IDL to throw an exception like so: {code:thrift} exception EchoException { } service EchoService { string echo(1: string message) throws (1: EchoException noEcho) void explode() } {code} The resulting processor code now includes appropriate {{rescue}} clauses based off the IDL. {code:ruby} class Processor include ::Thrift::Processor 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 def process_explode(seqid, iprot, oprot) args = read_args(iprot, Explode_args) result = Explode_result.new() @handler.explode() write_result(result, oprot, 'explode', seqid) end end {code} This is where my confusion begins and hopefully we can clear that up. Now it's time to implement this {{EchoService}} in ruby. An example handler would be: {code:ruby} class Handler def echo(string) string end end {code} This this is a correct implementation and will behave correctly with the thrift servers in the ruby library. Now if the {{Handler}} class is implemented incorrectly like so: {code:ruby} class Handler def echo(string) nil end end {code} 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 behavior based on my reading. Now if we change the handler to fail in a different way. {code:ruby} class Handler def echo(string) fail "Unexpected error!" end end {code} If a client calls the {{echo}} RPC the server will fail in different ways. Using the thread pool server, the thread handling that RPC dies and exits. The client receives a {{TTransportException}} and if uncaught the process exits. It's my understanding that we should be able to wrap all the service handlers in something like: {code:ruby} 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. Is this the correct behavior or should I be able to wrap my calls to catch exceptions and forward them as {{TApplicationException}} to clients? > 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)