From 2d2b3b2be861434a06a15c414b935fe7531b9752 Mon Sep 17 00:00:00 2001 From: Jens Geyer Date: Mon, 13 May 2013 22:03:08 +0200 Subject: [PATCH] THRIFT-1962 Multiplex processor should send any TApplicationException back to client Patch: Jens Geyer --- lib/delphi/src/Thrift.Processor.Multiplex.pas | 52 +++++++++++++++---- 1 file changed, 43 insertions(+), 9 deletions(-) diff --git a/lib/delphi/src/Thrift.Processor.Multiplex.pas b/lib/delphi/src/Thrift.Processor.Multiplex.pas index b771d437..8d6d8b0c 100644 --- a/lib/delphi/src/Thrift.Processor.Multiplex.pas +++ b/lib/delphi/src/Thrift.Processor.Multiplex.pas @@ -77,6 +77,9 @@ type private FServiceProcessorMap : TDictionary; + procedure Error( const oprot : IProtocol; const msg : IMessage; + extype : TApplicationException.TExceptionType; const etxt : string); + public constructor Create; destructor Destroy; override; @@ -138,6 +141,27 @@ begin end; +procedure TMultiplexedProcessorImpl.Error( const oprot : IProtocol; const msg : IMessage; + extype : TApplicationException.TExceptionType; + const etxt : string); +var appex : TApplicationException; + newMsg : IMessage; +begin + appex := TApplicationException.Create( extype, etxt); + try + newMsg := TMessageImpl.Create( msg.Name, TMessageType.Exception, msg.SeqID); + + oprot.WriteMessageBegin(newMsg); + appex.Write(oprot); + oprot.WriteMessageEnd(); + oprot.Transport.Flush(); + + finally + appex.Free; + end; +end; + + function TMultiplexedProcessorImpl.Process(const iprot, oprot : IProtocol) : Boolean; var msg, newMsg : IMessage; idx : Integer; @@ -152,21 +176,31 @@ begin // Use the actual underlying protocol (e.g. TBinaryProtocol) to read the message header. // This pulls the message "off the wire", which we'll deal with at the end of this method. msg := iprot.readMessageBegin(); - if not (msg.Type_ in [TMessageType.Call, TMessageType.Oneway]) - then raise TApplicationException.Create( TApplicationException.TExceptionType.InvalidMessageType, - ERROR_INVALID_MSGTYPE); - + if not (msg.Type_ in [TMessageType.Call, TMessageType.Oneway]) then begin + Error( oprot, msg, + TApplicationException.TExceptionType.InvalidMessageType, + ERROR_INVALID_MSGTYPE); + Exit( FALSE); + end; + // Extract the service name idx := Pos( TMultiplexedProtocol.SEPARATOR, msg.Name); - if idx < 1 - then raise TApplicationException.Create( TApplicationException.TExceptionType.InvalidProtocol, - Format(ERROR_INCOMPATIBLE_PROT,[msg.Name])); + if idx < 1 then begin + Error( oprot, msg, + TApplicationException.TExceptionType.InvalidProtocol, + Format(ERROR_INCOMPATIBLE_PROT,[msg.Name])); + Exit( FALSE); + end; // Create a new TMessage, something that can be consumed by any TProtocol sService := Copy( msg.Name, 1, idx-1); if not FServiceProcessorMap.TryGetValue( sService, processor) - then raise TApplicationException.Create( TApplicationException.TExceptionType.InternalError, - Format(ERROR_UNKNOWN_SERVICE,[sService])); + then begin + Error( oprot, msg, + TApplicationException.TExceptionType.InternalError, + Format(ERROR_UNKNOWN_SERVICE,[sService])); + Exit( FALSE); + end; // Create a new TMessage, removing the service name Inc( idx, Length(TMultiplexedProtocol.SEPARATOR)); -- 2.17.1