Justin Mills created THRIFT-3781:
------------------------------------

             Summary: [ruby] Thrift::Client can become permanently corrupt when 
Thrift::ProtocolException is raised
                 Key: THRIFT-3781
                 URL: https://issues.apache.org/jira/browse/THRIFT-3781
             Project: Thrift
          Issue Type: Bug
          Components: Ruby - Library
    Affects Versions: 0.9.3
            Reporter: Justin Mills


{{Thrift::Client#send_message_args}} rescues from {{StandardError}}, but 
{{Thrift::ProtocolException}} inherits from {{Exception}}. This means if you 
have an argument to a function that is not valid (ie, missing a required 
attribute), you can get the following error: 
{code}
Thrift::ProtocolException: Required field address is unset!
        from 
~/.rvm/gems/ruby-2.3.0/gems/my-thrift-gem-1.0/lib/my-thrift-gem/gen-rb/my-thrift-gem_types.rb:32:in
 `validate'
        from 
~/.rvm/gems/ruby-2.3.0/gems/thrift-0.9.3.0/lib/thrift/client.rb:44:in `write'
        from 
~/.rvm/gems/ruby-2.3.0/gems/thrift-0.9.3.0/lib/thrift/client.rb:44:in 
`send_message_args'
        from 
~/.rvm/gems/ruby-2.3.0/gems/thrift-0.9.3.0/lib/thrift/client.rb:30:in 
`send_message'
        from 
~/.rvm/gems/ruby-2.3.0/gems/my-thrift-gem-1.0/lib/my-thrift-gem/gen-rb/my_service.rb:22:in
 `send_example_1'
        from 
~/.rvm/gems/ruby-2.3.0/gems/my-thrift-gem-1.0/lib/my-thrift-gem/gen-rb/my_service.rb:17:in
 `example_1'
{code}

Since ProtocolException is not a StandardError, the exception handler is not 
called, and the {{@oprot.trans.close}} line is not executed, leaving the 
transport with data in it's buffers. All subsequent calls will fail that try to 
re-use this client because of this data.

It is also possible that this problem only occurs when the validation error 
happens in the 2nd and beyond arguments to a function, as only then is data 
likely to have been written.

I can see a couple of potential fixes:
- Make Thrift::ProtocolException inherit from StandardError
- Change the rescue block in client.rb to rescue from all Thrift exceptions 
that do not inherit from StandardError
- Have the client validate each parameter before attempting to serialize 
anything, ensuring that the data is more likely to serialize successfully.

>From a ruby perspective, I think the first of these is the best fix as I'm not 
>sure a ProtocolException is something that warrants subclassing directly from 
>Exception. It seems more aligned to IOError. Unless the thought here is that 
>ProtocolExceptions are reserved for cases where the client should be abandoned 
>and re-built. If that's the case, I think the last of the options might be 
>best since data validation could be done prior to serialization and need not 
>waste the effort of serialization, nor burn the client connection because of 
>it.



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

Reply via email to