Can I handle service errors myself within SOI?

1238
3
06-10-2020 11:25 PM
MarisSamats
New Contributor

Hello,

When users calls applyEdits on our FeatureService, and get's something wrong with the request - it just returns "unable to complete operation". Is it possible, to somehow get the detailed error (from SOI), so I could change the response, and append detailed error message? I know - detailed message is logged in the ArcGIS server logs, but that doesn't help, when the user is doing something, and I want to return detailed error to the user myself!

0 Kudos
3 Replies
nicogis
MVP Frequent Contributor
public byte[] HandleRESTRequest(string Capabilities, string resourceName, string operationName,
            string operationInput, string outputFormat, string requestProperties, out string responseProperties)
        {
            try
            {

                responseProperties = null;
                _serverLog.LogMessage(ServerLogger.msgType.infoStandard, _soiName + ".HandleRESTRequest()",
                    200, "Request received in Server Object Interceptor for handleRESTRequest");

                try
                {
                    IServerEnvironmentEx se4 = _restSOIHelper.ServerEnvironment as IServerEnvironmentEx;
                    IEnumServerDirectoryInfo dirInfos = se4.GetServerDirectoryInfos() as IEnumServerDirectoryInfo;
                    dirInfos.Reset();
                    IServerDirectoryInfo2 dirInfo = dirInfos.Next() as IServerDirectoryInfo2;
                    string _PathSystem = null;
                    while (dirInfo != null)
                    {
                        var dinfo2 = dirInfo as IServerDirectoryInfo2;
                        if (null != dinfo2 && dinfo2.Type == esriServerDirectoryType.esriSDTypeSystem)
                        {
                            _PathSystem = dinfo2.Path;
                            break;
                        }
                        dirInfo = dirInfos.Next() as IServerDirectoryInfo2;
                    }
                }
                catch { }

                // Find the correct delegate to forward the request too
                IRESTRequestHandler restRequestHandler = _restSOIHelper.FindRequestHandlerDelegate<IRESTRequestHandler>();
                if (restRequestHandler == null)
                    throw new RestErrorException("Service handler not found");

                var a = restRequestHandler.HandleRESTRequest(
                        Capabilities, resourceName, operationName, operationInput,
                        outputFormat, requestProperties, out responseProperties);

                //"{\"error\":{\"code\":500,\"message\":\"Unable to complete operation.\",\"details\":[\"No edits ('adds', 'updates', 'deletes', or 'attachment edits') were specified.\"]}}";
                string json = System.Text.Encoding.UTF8.GetString(a);

                if (errorinjson)
                {
                    // here if you have error change 'message' in json string
                    

                    return System.Text.Encoding.UTF8.GetBytes(json);
                }
                else
                    return restRequestHandler.HandleRESTRequest(
                        Capabilities, resourceName, operationName, operationInput,
                        outputFormat, requestProperties, out responseProperties);
            }
            catch (RestErrorException e)
            {
                responseProperties = "{\"Content-Type\":\"text/plain;charset=utf-8\"}";
                return System.Text.Encoding.UTF8.GetBytes(e.Message);
            }
        }‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

you can write similar code 

for filter requests interested you see also operationname == 'applyEdits' , capabilites == 'Create,Query,Update,Delete,Uploads...', resourceName == 'layers/xxx' ect...

0 Kudos
MarisSamats
New Contributor

Thank you for your answer. But all I get in the response is 

{"error":{"code":400,"message":"Unable to complete operation.","details":[]}}

In example:
In the SOI handler:

IRESTRequestHandler restRequestHandler = _restSOIHelper.FindRequestHandlerDelegate();

if (restRequestHandler == null) return null;

var result = restRequestHandler.HandleRESTRequest( Capabilities, resourceName, operationName, operationInput, outputFormat, requestProperties, out responseProperties);

var resultText = Encoding.UTF8.GetString(result);

return result;

I make an invalid request to query - WHERE OBJECTID IN ()
In the resultText - all I see is {"error":{"code":400,"message":"Unable to complete operation.","details":[]}}

(I attached to the process, and I see it while debugging)
In ArcGIS logs, I can see the details; An invalid where clause or definition expression has been requested: "OBJECTID IN ()"

Why is the details always empty?

0 Kudos
nicogis
MVP Frequent Contributor

see link: SOI Error

The SOI request handler will wrap this exception and let the server handle this exception. It hides the detailed error message in the response but automatically logs the message in server logs. This approach works better for failures that help the server administrator troubleshoot and are not intended to be revealed to the client applications.

0 Kudos