You are not logged in.
Pages: 1
Hi
Is it possible to override mormot's response and return Http 400 "Bad request" in Interfaced-based service? (In case if we want to make additional validation of incoming parameters).
Regards, Tomek
Offline
Try:
CurrentServiceContextServer.Error(400,'error message');
I don't remember the exact sintax.
Esteban
Offline
Hi
I've tried, but it doesn't seem to work, it still returns 200:
function TRemoteSrv.Test(aParams: UTF8String): UTF8String;
begin
//Result := 'Test(' + aParams + ')';
//ServiceContext.Request.Error('Wrong param value', 400);
// CurrentServiceContextServer.... no "Error" method
CurrentServiceContext.Request.Error('Wrong param value', 400);
end;
Regards, Tomek
Last edited by tomek (2019-06-18 06:40:33)
Offline
Try (not tested):
CurrentServiceContext.Request.Returns('Wrong param value', 400);
Offline
Hi,
If I'm not wrong, the way to return custom response it's via TServiceCustomAnswer record type.
Please check related section in documentation for further details.
Offline
I tested it and it really does not work.
At some point of TServiceFactoryServer.ExecuteMethod the status is forced to 200.
60129 Ctxt.Call.OutStatus := HTTP_SUCCESS;
A TServiceCustomAnswer should be used as mentioned by @xalo.
The problem of this in my view is that it loses the standard functionality and it is mandatory to use this type of result.
It may be best to return status 200 and error details in JSON. Something like
{"error": "No validated", "code:" 123}
Offline
Don't use TServiceCustomAnswer, if you feel like that's what you need then use method based services instead, that will give you all the customization you want.
Instead, like @macfly said, your service defined interface methods should have an out parameter specifying your custom result code :
procedure DoSomething(const X,Y,Z : Integer; out Result: TResult); // where TResult is an Enum type
Http codes are great for connection, session status, anything else, introduce your own.
Offline
pnv0 is in the right way, from my point of view.
Ensure you read https://synopse.info/files/html/Synopse … l#TITL_165
In short: for interface-based services, don't rely on HTTP error codes, but define some enumeration types, used to return the state/error of the process.
And set the first enumerate (mapped as 0 in JSON) as "successful state" - this would be the default value, e.g. for mocking.
If you want to have some HTTP status code returned, use method-based services - or TServiceCustomAnswer with interface-based services, but it is not the best pattern just for handling errors, since you would need manual marshalling of the returned JSON, and generate week RTTI information (not good for the documentation, or the client code generation).
Offline
Thank you all for tips and possible solutions.
The problem is, that server is made for third party client, and client side developers are quite reluctant to interpreting custom answers with http 200.
Regards, Tomek
Offline
Thank you all for tips and possible solutions.
The problem is, that server is made for third party client, and client side developers are quite reluctant to interpreting custom answers with http 200.Regards, Tomek
If i understood it right, you want to do something like this ?
if FConnection.SetUser(AAuthSettings.GetUSerName, AAuthSettings.GetPassWord) then
begin
aStatus := FConnection.CallBackGet(
'Autentication', [
'Id', AAuthSettings.GetId.ToString
], aOut
);
Result := (aStatus = 200);
case aStatus of
200:
begin
Result := True;
AMessage := 'OK';
end;
400:
begin
Result := False;
AMessage := 'Conection limit!';
end;
401:
begin
Result := False;
AMessage := 'Route Blocked';
end
Offline
A proposal to allow return an error status is to use exceptions.
Since a status error is being returned conscientiously, I believe no pattern is being broken.
Something like:
ESynServiceJSONException = class(ESynServiceException)...
contructor Create(Status, AMessage: RawUtf8; Result : Variant);
end;
Then...
function TRemoteSrv.Test(aParams: UTF8String): UTF8String;
begin
if not Validated(...) then
raise ESynServiceJSONException.Create(400, 'Not validated', _Obj(['name','Can not be empty']));
end;
Produces
// 400 Not validated
{"result":{
"name":"Can not be empty"
}}
Last edited by macfly (2019-06-21 18:33:46)
Offline
Pages: 1