views:

535

answers:

4

I am integrating with MS Dynamics GP WebServices from C# and I am not sure how to handle exception.

If I do a GetCustomer with a inexistant ID, the web services return me a "generic" SoapException and the message is "Business object not found." So the only way I see to be sure it's an invalid ID and not any other error, is by parsing the error message, I find this solution extremely fragile. My GP version is English, on customer site it's gonna be french and I have no idea in which language web services message gonna be. I am thinking about catching it, parsing the message and throw a more meaningful error type.

Do you see a better option ?

A: 

Are you in control over the WebService code?

In that case I would return SoapExceptions with simple error codes that are easier to parse and let the client application decide what message to display based and the parsed error code.

You could use an "Error codes" enum on the WebService to make the code more readable.

//Example
enum ErrorCodes
{
  BusinessObjectNotFound = 1000,
  AnotherPossibleError = 1002
}

try
{
//Code
}
Catch(BusinessObjectNotFoundException bex)
{
  throw new SoapException(ErrorCodes.BusinessObjectNotFound);
  //Or maybe...
  //throw new SoapException(((int)ErrorCodes.BusinessObjectNotFound).ToString());
}
Jesper Palm
No this the error Dynamics GP is throwing at me.
pmlarocque
+1  A: 

Unfortunately both the eConnect API and the GP Web Services both return generic errors, just be glad you don't have to parse the eConnect ones.

Good things is, the errors are generally static, so you can build parsers for them. Creating custom exceptions is definitely a good way to do it with this type of web service.

Tom Anderson
Thanks, yes I was glad to see that all the services I needed were available via web services or I would have trap with eConnect.
pmlarocque
eConnect is a pain, not to mention the additional costs for the customer. We are using it with about 10 different clients and the only good thing about eConnect is how verbose the errors are, and you can always get the eConnect errors in the event viewer.
Tom Anderson
+1  A: 

I have a blog post that details how I overcame this question in WCF (though as you can see, I don't mind parsing the error message to get the details). Here's the meat of it:

catch (FaultException soapEx)
{
    MessageFault mf = soapEx.CreateMessageFault();
    if (mf.HasDetail)
    {
        XmlDictionaryReader reader = mf.GetReaderAtDetailContents();
        Guid g = reader.ReadContentAsGuid();
    }
}

Once you have the GUID you can use it to query the GP Web Service for the details of the error.

Jacob Proffitt
Thanks will investigate.
pmlarocque
The web service method you want for the details is GetLoggedValidationResultByKey (which returns a useful result object).
Jacob Proffitt
It's a step in the right direction but it does not work. In GP helps. I says to get the Guid needed by "GetLoggedValidationResultByKey" from "soapErr.Detail.InnerText" and in the case of "GetCustomerByKey" is invalid key, that property is empty.... I'll just parse the error for now I think.
pmlarocque
I should have mentioned that that snippet works for WCF rather than vanilla webservices...
Jacob Proffitt
A: 

For information to people interested in the topics, Jacob Proffitt response look like the way to go. here a snipper from Dynamics GP documentation:

catch(SoapException soapErr)
{
    // If a validation exception occurred, the logid will be in a child node
    if(soapErr.Detail.HasChildNodes == true)
    {
        // Create a guid for the logid value in the soap exception
        Guid guid = new Guid(soapErr.Detail.InnerText);

        // Get the validation result object
        validationResult = wsDynamicsGP.GetLoggedValidationResultByKey(guid, context);

        // Display the number of validation exceptions
        MessageBox.Show("Number of validation exceptions: " +
        validationResult.Errors.Length.ToString());
    }

}

But in the case I cited : GetCustomer with an unexisting ID, the line "soapErr.Detail.HasChildNodes" is false so it fails.

The webservices seem full of funny behavior, this will take longer than I expected :(.

pmlarocque