@@ -8,53 +8,105 @@ interface
8
8
9
9
uses
10
10
{ $IF DEFINED(FPC)}
11
- SysUtils,
11
+ SysUtils, fpjson,
12
12
{ $ELSE}
13
- System.SysUtils,
13
+ System.SysUtils, System.JSON,
14
14
{ $ENDIF}
15
15
Horse, Horse.Commons;
16
16
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;
18
29
19
30
implementation
20
31
21
32
uses
22
33
{ $IF DEFINED(FPC)}
23
- fpjson, TypInfo;
34
+ TypInfo;
24
35
{ $ELSE}
25
- System.JSON, System. TypInfo;
36
+ System.TypInfo;
26
37
{ $ENDIF}
27
38
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);
29
43
begin
30
44
ARes.Send<TJSONObject>(AJson).Status(AStatus);
31
45
end ;
32
46
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} );
34
64
var
35
65
LJSON: TJSONObject;
36
66
LStatus: Integer;
67
+ lSendException: Boolean;
37
68
begin
38
69
try
39
70
Next();
40
71
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 ;
48
72
on E: Exception do
49
73
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 ;
56
97
end ;
57
98
end ;
58
99
end ;
59
100
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
+
60
112
end .
0 commit comments