You are not logged in.
As far as I know, by my testings and by reading also the following reply of ab in a previous forum topic:
https://synopse.info/forum/viewtopic.php?pid=9445#p9445
error messages in interface bases services are returning to clients using exceptions. I've noticed however that this is returned to a web client not in the usual json format with ErrorCode, ErrorText properties. Instead the repsonseJSON is an object, with its textual representation given by another property, responseText as follows:
responseText: "{\r\n\"errorCode\":500,\r\n\"error\":\r\n{\"EServiceException\":{\r\n\t\"ClassName\":\"EServiceException\",\r\n\t\"Address\":\" $0000000000690839 CHANGEPASSWORD, line 36 of bareservice.pas\",\r\n\t\"Message\": \"My error message\"\r\n}}\r\n}"
Is there any way to handle errors in interface based service implementations, so to be sent back to web browsers as ErrorCode,ErrorText jsons with less severe error codes than 500?
Last edited by damiand (2021-02-18 16:40:29)
Offline
Please read https://synopse.info/files/html/Synopse … l#TITL_165
TL&DR: don't use exceptions but explicitly error codes (e.g. enumerates) for error notification to the client side.
Exceptions should only indicate "panic" problems, just as with GoLang.
Offline
OK thanks, but should I use TCQRSQueryObject and ICQRSService whenever I want a proper error handling? If I have a simple TInterfacedObject descendant service, implementing an IInvokable descendant interface what should I use inside a service method to pass the error to the web client?
Last edited by damiand (2021-02-17 15:13:37)
Offline
No, those CQRS types are just an example.
Define your own set of enumerations, probably local to each interface service itself.
Thinks from the end-user perspective: which error codes are easy to understand when consuming the service on the client side?
Offline
Thanks a lot ab you are very clear in functional terms, but my problem is how to make the system interpret the enumerated code returned by the interface method to respond with an HTTP_BADREQUEST, together with a json with ErrorCode, ErrorText properties. By just returning the second enumerated value the system responds with an HTTP_OK and the web client interprets this as a normal execution.
My (seemly unorthodox) solution is the following:
1. Inherit the service class from an TInterfacedObjectWithCustomCreate and add a method of TNotifyErrorURI type, where I catch the EServiceExcepton and call Ctx.Error accordingly:
function TBareService.NotifyErrorURI(Ctxt: TSQLRestServerURIContext;
E: Exception): boolean;
begin
if E is EServiceException then
begin
Ctxt.Error(E.Message);
Result := false
end
else Result := true
end;
2. In the overridden constructor I linked the sever's OnErrorURI event to the aforementioned method:
inherited Create;
aServer.OnErrorURI := @NotifyErrorURI;
3. Raise inside the service method an EServiceException according to my error checking logic with a descriptive message to the client.
I would clearly prefer the return of enumerated values but obviously I missed the way to do it, as I explained in my first paragraph.
Ps. This topic is similar to the following old forum topic: https://synopse.info/forum/viewtopic.php?id=4293
Last edited by damiand (2021-02-18 09:56:04)
Offline
All your problems would go away if you used method based services instead (recommended for web clients).
Offline