Web API Helper code: CrmHttpResponseException class

 

Applies To: Dynamics 365 (online), Dynamics 365 (on-premises), Dynamics CRM 2016, Dynamics CRM Online

Use the CrmHttpResponseException class to represent HTTP status errors generated during Dynamics 365 Web API calls. This class is derived from the standard .NET System.Exception class to easily integrate with your existing exception-handling mechanisms. For more general information, see Handling and Throwing Exceptions.

The CrmHttpResponseException class is located in the file Exceptions.cs in the CRM SDK Web API Helper Library. It is used extensively in the other helper library classes and C# Web API samples. For more information, see Use the Microsoft Dynamics 365 Web API Helper Library (C#).

This class utilizes JSON string-handling functionality from the open source Json.NET library.

Class members

The following table shows the public members of the CrmHttpResponseException class.

Dynamics 365 Web API Helper Library-CrmHttpResponseException Class Diagram

CrmHttpResponseException class

Properties:

StackTrace – the string representation of the immediate frames on the Dynamics 365 server’s call stack when the exception was thrown, if available.


Methods:

The constructors initialize an instance of this class, and require a HttpContent parameter and an optional inner exception parameter.

ExtractMessageFromContent – this static method extracts the error message from the specified HTTP content parameter.

Usage

Typically, you create and throw a CrmHttpResponseException object when processing a status error returned with a HTTP response message. For example, the following code throws such an error when the WhoAmI Function function call fails.

response = await httpClient.GetAsync("WhoAmI", HttpCompletionOption.ResponseContentRead);
if (!response.IsSuccessStatusCode)
{ 
    throw new CrmHttpResponseException(response.Content); 
}

You can catch and process thrown CrmHttpResponseException objects similarly to other standard .NET exceptions.

Important

If you are using the HttpResponseMessage.EnsureSuccessStatusCode method to automatically convert HTTP response errors into thrown HttpRequestException objects, then this approach precludes the use of the CrmHttpResponseException class. Note that if you use this approach, much of the response message details, including the status code, will not be available during exception handling.

Class listing

The most current source for this class is found in the CRM SDK Web API Helper Library NuGet package.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Http;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace Microsoft.Crm.Sdk.Samples.HelperCode
{
    /// <summary>
    /// Produces a populated exception from an error message in the content of an HTTP response. 
    /// </summary>
    public class CrmHttpResponseException : System.Exception
    {
        #region Properties
        private static string _stackTrace;

        /// <summary>
        /// Gets a string representation of the immediate frames on the call stack.
        /// </summary>
        public override string StackTrace
        {
            get { return _stackTrace; }
        }
        #endregion Properties

        #region Constructors
        /// <summary>
        /// Initializes a new instance of the CrmHttpResponseException class.
        /// </summary>
        /// <param name="content">The populated HTTP content in Json format.</param>
        public CrmHttpResponseException(HttpContent content)
            : base(ExtractMessageFromContent(content)) { }

        /// <summary>
        /// Initializes a new instance of the CrmHttpResponseException class.
        /// </summary>
        /// <param name="content">The populated HTTP content in Json format.</param>
        /// <param name="innerexception">The exception that is the cause of the current exception, or a null reference
        /// if no inner exception is specified.</param>
        public CrmHttpResponseException(HttpContent content, Exception innerexception)
            : base(ExtractMessageFromContent(content), innerexception) { }

        #endregion Constructors

        #region Methods
        /// <summary>
        /// Extracts the CRM specific error message and stack trace from an HTTP content. 
        /// </summary>
        /// <param name="content">The HTTP content in Json format.</param>
        /// <returns>The error message.</returns>
        private static string ExtractMessageFromContent(HttpContent content)
        {
            string message = String.Empty;
            string downloadedContent = content.ReadAsStringAsync().Result;
            if (content.Headers.ContentType.MediaType.Equals("text/plain"))
            {
                message = downloadedContent;
            }
            else if (content.Headers.ContentType.MediaType.Equals("application/json"))
            {
                JObject jcontent = (JObject)JsonConvert.DeserializeObject(downloadedContent);
                IDictionary<string, JToken> d = jcontent;

                // An error message is returned in the content under the 'error' key. 
                if (d.ContainsKey("error"))
                {
                    JObject error = (JObject)jcontent.Property("error").Value;
                    message = (String)error.Property("message").Value;
                }
                else if (d.ContainsKey("Message"))
                    message = (String)jcontent.Property("Message").Value;

                if (d.ContainsKey("StackTrace"))
                    _stackTrace = (String)jcontent.Property("StackTrace").Value;
            }
            else if (content.Headers.ContentType.MediaType.Equals("text/html"))
            {
                message = "HTML content that was returned is shown below.";
                message += "\n\n" + downloadedContent;
            }
            else
            {
                message = String.Format("No handler is available for content in the {0} format.",  
                    content.Headers.ContentType.MediaType.ToString());
            }
            return message;
            #endregion Methods
        }
    }
}

See Also

Get started with the Microsoft Dynamics 365 Web API (C#)
Start a Dynamics 365 Web API project in Visual Studio (C#)
Use the Microsoft Dynamics 365 Web API Helper Library (C#)
Web API Helper code: Authentication class
Web API Helper code: Configuration classes

Microsoft Dynamics 365

© 2017 Microsoft. All rights reserved. Copyright