thrift-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Rush Manbert <r...@manbert.com>
Subject Re: Using TApplicationException - need example
Date Thu, 17 May 2012 16:44:30 GMT

On May 16, 2012, at 10:07 PM, Steve Angelovich wrote:

> What is TApplicationException intended to be used for?
> 
> Is there a mechanism in thrift to propagate a runtime exception from the server back
to the client?
> 
> How do others deal with a case where the caller has made an RPC call with an invalid
argument.  In Java I'd normally throw a IllegalArgumentException, is something like this possible
in thrift or do I have to add another user defined exception type which will result in the
caller having to deal with another checked exception.
> 
> 
> Thanks for any help
> Steve
> 
> 
> On 05/10/2012 05:06 PM, Craig Artley wrote:
> 
> 
> Hello, I want to take exceptions on the server and return them back to the client. For
example, say the client's request leads to a run time exception like IllegalArgumentException.
I think that TApplicationException with INTERNAL_ERROR is the way to do this, but I couldn't
get it to work and I can't find any examples.
> 
> In my service handler, I check the args.  If they are invalid, I threw a TApplicationException
like this
>  throw new TApplicationException(TApplicationException.INTERNAL_ERROR,"Illegal argument
blah blah");
> 
> It still showed up in my client as a TTransportException:
> org.apache.thrift.transport.TTransportException
>    at org.apache.thrift.transport.TIOStreamTransport.read(TIOStreamTransport.java:132)
> 
> I'm sure I am just misunderstanding something.  What am I missing? Can anyone provide
an example of robust exception handling in the server to the client?
> 
> I read about it in THRIFT-378
> https://issues.apache.org/jira/browse/THRIFT-378
> 
> Regards,
>  -craig

You can define your own exception types. Here's a real world example:

-----------------------------------------------------
File OurThriftException.thrift:
struct ExceptionInfoAll
{
	1: string 	name,		/** The class name of the exception */
	2: string 	message,	/** If not a OurCustomException, this is the result of what().
					    If OurCustomException, this is the result of ex.toString(). */
}

struct ExceptionInfoOurCustomException
{
	1: string 	errorCodeName,	/** The name of the error, such as DeviceNotFound
								    This is specific to the exception class */
	2: i32		errorCodeValue,	/** The numeric value of the error code */
	3: string	description,	/** The description string defined in the exception's EXCEPTION_TABLE
*/
	4: string	debugMsg,	/** The debug message attached to the exception at the throw point */
	5: string	location,	/** The location information that may have been attached at the throw
point. */
}

struct ExceptionInfo
{
	1: ExceptionInfoAll 				defaultInfo,		/** Available for any exception */
	2: optional ExceptionInfoOurCustomException	ourInfo,		/** Available only for OurCustomException
*/
}

exception OurThriftExceptionWire
{
	1: ExceptionInfo 			excInfo,	/** The information extracted from the exception that was caught
by the server. */
}
-----------------------------------------------------


Once you do this, you can define a service like this:

service MyService
{
	returnType myCall ( args here)  throws (1: OurThriftException. OurThriftExceptionWire ex),
}

On your server side, you do this (I have neglected to set the __isset values to make the code
clearer.):

returnType myCall_handler (args)
{

	try
	{
		do something
	}
	catch (OurCustomException &ex)
	{
		OurThriftExceptionWire wireEx;

		wireEx.excInfo.defaultInfo = "OurCustomException";
		wireEx.excInfo.defaultInfo.message = ex.what();

		// Extract info from OurCustomException here and pack into wireEx.excInfo.ourInfo

		throw wireEx;
	}
	catch (std::exception &ex)
	{
		OurThriftExceptionWire wireEx;

		wireEx.excInfo.defaultInfo = "OurCustomException";
		wireEx.excInfo.defaultInfo.message = ex.what();

		throw wireEx;

	}
}

And on your client side you do this:

try
{
	myCall (args)
}
catch (OurThriftExceptionWire &ex)
{
	// Now you have exception details from the server side. We would throw an exception type
	// specific to the library where this code is, but it would contain all the info from
	// ex.excInfo.
}

I hope that helps.

Best regards,
Rush
Mime
View raw message