@@ -8,53 +8,105 @@ interface
88
99uses
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
1930implementation
2031
2132uses
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);
2943begin
3044 ARes.Send<TJSONObject>(AJson).Status(AStatus);
3145end ;
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} );
3464var
3565 LJSON: TJSONObject;
3666 LStatus: Integer;
67+ lSendException: Boolean;
3768begin
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 ;
5899end ;
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+
60112end .
0 commit comments