You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@thrift.apache.org by "Kumar, Ganesh" <ku...@deshaw.com> on 2014/03/18 14:13:53 UTC

Thrift Python Client fails to recover if arguments passed aren't of expected type

Hello,

If a service exposed through python client doesn't get the arguments of expected type (like if it gets string in place of i32), the exception isn't handled cleanly, and the transport needs to be closed & reopened for the client to be used again.

Suppose there is a service 'add' with its arguments of type i32, and the call has been with type of argument as string. Since there is no check on type of arguments till the protocol layer is reached, where struct.pack is called (for TBinaryProtocol )to serialize the value on the underlying transport. Now at this point an exception is thrown which is propagated upwards to the client caller. But the transport buffer isn't cleared (it seems there aren't any API also to clear the buffer), when the next call is made through the same client, the previous contents on buffer gets sent to the server, and an erroneous reply is received. Next call onwards the connection gets stuck and client keeps on waiting.

Is there a way to solve this problem, or a workaround?

Thanks,
Ganesh


Example:

service Adder {
        i32 add(1: i32 a, 2: i32 b),
}

In [31]: client.add(11,2)
Out[31]: 13

In [32]: client.add(11, '2')
Error
.....
error: required argument is not an integer

In [33]: client.add(12, 2)
Out[33]: -2147418100


Re: Thrift Python Client fails to recover if arguments passed aren't of expected type

Posted by James Haggerty <mu...@gmail.com>.
The PHP Thrift client has similar problems if there's an error somewhere in
the stack. The safest thing to do after any kind of protocol related
TException is to do the close/reopen on the transport, it seems.

We've made a small modification to the generator so that all the
user-defined classes inherit from TUserException, which at least makes it
easy to distinguish the 'good' exceptions from the bad ones.


On Wed, Mar 19, 2014 at 12:13 AM, Kumar, Ganesh <ku...@deshaw.com> wrote:

> Hello,
>
> If a service exposed through python client doesn't get the arguments of
> expected type (like if it gets string in place of i32), the exception isn't
> handled cleanly, and the transport needs to be closed & reopened for the
> client to be used again.
>
> Suppose there is a service 'add' with its arguments of type i32, and the
> call has been with type of argument as string. Since there is no check on
> type of arguments till the protocol layer is reached, where struct.pack is
> called (for TBinaryProtocol )to serialize the value on the underlying
> transport. Now at this point an exception is thrown which is propagated
> upwards to the client caller. But the transport buffer isn't cleared (it
> seems there aren't any API also to clear the buffer), when the next call is
> made through the same client, the previous contents on buffer gets sent to
> the server, and an erroneous reply is received. Next call onwards the
> connection gets stuck and client keeps on waiting.
>
> Is there a way to solve this problem, or a workaround?
>
> Thanks,
> Ganesh
>
>
> Example:
>
> service Adder {
>         i32 add(1: i32 a, 2: i32 b),
> }
>
> In [31]: client.add(11,2)
> Out[31]: 13
>
> In [32]: client.add(11, '2')
> Error
> .....
> error: required argument is not an integer
>
> In [33]: client.add(12, 2)
> Out[33]: -2147418100
>
>