Skip to content

Commit 2beabec

Browse files
Merge pull request #19 from antoniojmsjr/master
Novo recurso no middleware para interceptar as exceções gerada na API
2 parents 778a38e + 4b84d50 commit 2beabec

File tree

1 file changed

+72
-20
lines changed

1 file changed

+72
-20
lines changed

src/Horse.HandleException.pas

Lines changed: 72 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,53 +8,105 @@ interface
88

99
uses
1010
{$IF DEFINED(FPC)}
11-
SysUtils,
11+
SysUtils, fpjson,
1212
{$ELSE}
13-
System.SysUtils,
13+
System.SysUtils, System.JSON,
1414
{$ENDIF}
1515
Horse, Horse.Commons;
1616

17-
procedure HandleException(Req: THorseRequest; Res: THorseResponse; Next: {$IF DEFINED(FPC)}TNextProc{$ELSE}TProc{$ENDIF});
17+
type
18+
{$IF DEFINED(FPC)}
19+
TInterceptExceptionCallback = {$IF DEFINED(HORSE_FPC_FUNCTIONREFERENCES)}reference to {$ENDIF}procedure(AException: Exception; AResponse: THorseResponse; var ASendException: Boolean);
20+
{$ELSE}
21+
TInterceptExceptionCallback = reference to procedure(AException: Exception; AResponse: THorseResponse; var ASendException: Boolean);
22+
{$ENDIF}
23+
24+
function HandleException: THorseCallback; overload;
25+
function HandleException(const ACallback: TInterceptExceptionCallback): THorseCallback; overload;
26+
procedure Middleware(Req: THorseRequest; Res: THorseResponse; Next: {$IF DEFINED(FPC)}TNextProc{$ELSE}TProc{$ENDIF});
27+
28+
function FormatExceptionJSON(AException: Exception): TJSONObject;
1829

1930
implementation
2031

2132
uses
2233
{$IF DEFINED(FPC)}
23-
fpjson, TypInfo;
34+
TypInfo;
2435
{$ELSE}
25-
System.JSON, System.TypInfo;
36+
System.TypInfo;
2637
{$ENDIF}
2738

28-
procedure SendError(ARes:THorseResponse; AJson: TJSONObject; AStatus: Integer);
39+
var
40+
InterceptExceptionCallback: TInterceptExceptionCallback = nil;
41+
42+
procedure SendException(ARes: THorseResponse; AJson: TJSONObject; const AStatus: Integer);
2943
begin
3044
ARes.Send<TJSONObject>(AJson).Status(AStatus);
3145
end;
3246

33-
procedure HandleException(Req: THorseRequest; Res: THorseResponse; Next: {$IF DEFINED(FPC)}TNextProc{$ELSE}TProc{$ENDIF});
47+
function FormatExceptionJSON(AException: Exception): TJSONObject;
48+
var
49+
LEHorseException: EHorseException;
50+
begin
51+
if (AException is EHorseException) then
52+
begin
53+
LEHorseException := (AException as EHorseException);
54+
Result := {$IF DEFINED(FPC)}GetJSON(LEHorseException.ToJSON) as TJSONObject{$ELSE}TJSONObject.ParseJSONValue(LEHorseException.ToJSON) as TJSONObject{$ENDIF};
55+
end
56+
else
57+
begin
58+
Result := TJSONObject.Create;
59+
Result.{$IF DEFINED(FPC)}Add{$ELSE}AddPair{$ENDIF}('error', AException.Message);
60+
end;
61+
end;
62+
63+
procedure Middleware(Req: THorseRequest; Res: THorseResponse; Next: {$IF DEFINED(FPC)}TNextProc{$ELSE}TProc{$ENDIF});
3464
var
3565
LJSON: TJSONObject;
3666
LStatus: Integer;
67+
lSendException: Boolean;
3768
begin
3869
try
3970
Next();
4071
except
41-
on E: EHorseCallbackInterrupted do
42-
raise;
43-
on E: EHorseException do
44-
begin
45-
LJSON := {$IF DEFINED(FPC)}GetJSON(E.ToJSON) as TJSONObject{$ELSE}TJSONObject.ParseJSONValue(E.ToJSON) as TJSONObject{$ENDIF};
46-
SendError(Res, LJSON, Integer(E.Status));
47-
end;
4872
on E: Exception do
4973
begin
50-
LStatus := Res.Status;
51-
if (LStatus < Integer(THTTPStatus.BadRequest)) then
52-
LStatus := Integer(THTTPStatus.InternalServerError);
53-
LJSON := TJSONObject.Create;
54-
LJSON.{$IF DEFINED(FPC)}Add{$ELSE}AddPair{$ENDIF}('error', E.Message);
55-
SendError(Res, LJSON, LStatus);
74+
if (E is EHorseCallbackInterrupted) then
75+
raise;
76+
77+
lSendException := True;
78+
if Assigned(InterceptExceptionCallback) then
79+
InterceptExceptionCallback(E, Res, lSendException);
80+
81+
if not lSendException then
82+
Exit;
83+
84+
if (E is EHorseException) then
85+
begin
86+
LJSON := FormatExceptionJSON(E);
87+
SendException(Res, LJSON, Integer(EHorseException(E).Status));
88+
end
89+
else
90+
begin
91+
LStatus := Res.Status;
92+
if (LStatus < Integer(THTTPStatus.BadRequest)) then
93+
LStatus := Integer(THTTPStatus.InternalServerError);
94+
LJSON := FormatExceptionJSON(E);
95+
SendException(Res, LJSON, LStatus);
96+
end;
5697
end;
5798
end;
5899
end;
59100

101+
function HandleException: THorseCallback; overload;
102+
begin
103+
Result := HandleException(nil);
104+
end;
105+
106+
function HandleException(const ACallback: TInterceptExceptionCallback): THorseCallback; overload;
107+
begin
108+
InterceptExceptionCallback := ACallback;
109+
Result := Middleware;
110+
end;
111+
60112
end.

0 commit comments

Comments
 (0)