-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathPopulateResponseInfo.pas
111 lines (94 loc) · 3.33 KB
/
PopulateResponseInfo.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
unit PopulateResponseInfo;
interface
uses
Data.Cloud.CloudAPI,
IPPeerAPI;
type
TPopulateResponseInfo = class
public
procedure FromPeer(const ResponseInfo: TCloudResponseInfo; const Peer: IIPHTTP); overload;
procedure FromExceptionPeer(const ResponseInfo: TCloudResponseInfo; const ExceptionPeer: EIPHTTPProtocolExceptionPeer); overload;
end;
implementation
uses
Classes,
SysUtils,
XmlIntf,
XmlDoc;
{ TPopulateResponseInfo }
procedure TPopulateResponseInfo.FromExceptionPeer(const ResponseInfo: TCloudResponseInfo;
const ExceptionPeer: EIPHTTPProtocolExceptionPeer);
const
NODE_ERRORS = 'Errors';
NODE_ERROR = 'Error';
NODE_ERROR_MESSAGE = 'Message';
NODE_ERROR_CODE = 'Code';
NODE_REQUEST_ID = 'RequestId';
NODE_RESPONSE_METADATA = 'ResponseMetadata';
var
XmlDoc: IXMLDocument;
IsErrors: Boolean;
Aux, ErrorNode, MessageNode: IXMLNode;
ErrorCode, ErrorMsg: string;
begin
if ExceptionPeer.ErrorMessage.IsEmpty then
Exit;
XmlDoc := TXMLDocument.Create(nil);
XmlDoc.LoadFromXML(ExceptionPeer.ErrorMessage);
ResponseInfo.StatusCode := ExceptionPeer.ErrorCode;
ResponseInfo.StatusMessage := ExceptionPeer.Message;
IsErrors := AnsiPos(Format('<%s>', [NODE_ERRORS]), ExceptionPeer.ErrorMessage) > 0;
//Parse the error and update the ResponseInfo StatusMessage
if IsErrors or (AnsiPos('<ErrorResponse', ExceptionPeer.ErrorMessage) > 0) then
begin
//Amazon has different formats for returning errors as XML
if IsErrors then
begin
ErrorNode := xmlDoc.DocumentElement.ChildNodes.FindNode(NODE_ERRORS);
ErrorNode := ErrorNode.ChildNodes.FindNode(NODE_ERROR);
end
else
ErrorNode := xmlDoc.DocumentElement.ChildNodes.FindNode(NODE_ERROR);
if (ErrorNode <> nil) and (ErrorNode.HasChildNodes) then
begin
MessageNode := ErrorNode.ChildNodes.FindNode(NODE_ERROR_MESSAGE);
if (MessageNode <> nil) then
ErrorMsg := MessageNode.Text;
if ErrorMsg <> EmptyStr then
begin
//Populate the error code
Aux := ErrorNode.ChildNodes.FindNode(NODE_ERROR_CODE);
if (Aux <> nil) then
ErrorCode := Aux.Text;
ResponseInfo.StatusMessage := Format('%s - %s (%s)', [ResponseInfo.StatusMessage, ErrorMsg, ErrorCode]);
end;
end;
//populate the RequestId, which is structured differently than if this is not an error ResponseInfo
Aux := xmlDoc.DocumentElement.ChildNodes.FindNode(NODE_REQUEST_ID);
if (Aux <> nil) and (Aux.IsTextElement) then
begin
if not Assigned(ResponseInfo.Headers) then
ResponseInfo.Headers := TStringList.Create;
ResponseInfo.Headers.Values[NODE_REQUEST_ID] := Aux.Text;
end;
end
//Otherwise, it isn't an error, but try to pase the RequestId anyway.
else
begin
Aux := xmlDoc.DocumentElement.ChildNodes.FindNode(NODE_RESPONSE_METADATA);
if Aux <> nil then
begin
Aux := Aux.ChildNodes.FindNode(NODE_REQUEST_ID);
if Aux <> nil then
if not Assigned(ResponseInfo.Headers) then
ResponseInfo.Headers := TStringList.Create;
ResponseInfo.Headers.Values[NODE_REQUEST_ID] := Aux.Text;
end;
end;
end;
procedure TPopulateResponseInfo.FromPeer(const ResponseInfo: TCloudResponseInfo; const Peer: IIPHTTP);
begin
ResponseInfo.StatusCode := Peer.ResponseCode;
ResponseInfo.StatusMessage := Peer.ResponseText;
end;
end.