Commit 75c12bcd authored by Jason Williams's avatar Jason Williams Committed by GitHub
Browse files

Merge pull request #50 from WilliamsJason/master

Adds parsing of error data to exception handling
parents cf32eb53 672157a8
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -40,6 +40,8 @@ namespace Microsoft.Tools.WindowsDevicePortal.Tests
        /// <param name="response">The response to return.</param>
        public void AddMockResponse(string endpoint, HttpResponseMessage response)
        {
            Utilities.ModifyEndpointForFilename(ref endpoint);

            this.mockResponses.Add(endpoint.ToLowerInvariant(), response);
        }

+44 −1
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@
// </copyright>
//----------------------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
@@ -62,7 +63,7 @@ namespace Microsoft.Tools.WindowsDevicePortal.Tests
        public void UpdateXboxLiveUsersTest()
        {
            HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.NoContent);
            TestHelpers.MockHttpResponder.AddMockResponse(DevicePortal.XboxLiveUserApi);
            TestHelpers.MockHttpResponder.AddMockResponse(DevicePortal.XboxLiveUserApi, response);

            UserList users = new UserList();
            UserInfo user = new UserInfo();
@@ -76,5 +77,47 @@ namespace Microsoft.Tools.WindowsDevicePortal.Tests

            Assert.AreEqual(TaskStatus.RanToCompletion, updateUsersTask.Status);
        }

        /// <summary>
        /// Tests the failure case of trying to add a sponsored user
        /// when the maximum number is already on the console.
        /// </summary>
        [TestMethod]
        public void AddSponsoredUserTest_Failure()
        {
            HttpResponseMessage response = new HttpResponseMessage((HttpStatusCode)422);
            HttpContent content = new StringContent(
                "{\"ErrorCode\":-2136866553,\"ErrorMessage\":\"The maximum number of sponsored users is already signed in.\"}", 
                System.Text.Encoding.UTF8, 
                "application/json");

            response.Content = content;

            TestHelpers.MockHttpResponder.AddMockResponse(DevicePortal.XboxLiveUserApi, response);

            UserList users = new UserList();
            UserInfo user = new UserInfo();
            user.SponsoredUser = true;
            users.Add(user);

            try
            {
                Task updateUsersTask = TestHelpers.Portal.UpdateXboxLiveUsers(users);
                updateUsersTask.Wait();

                Assert.Fail("Expected an exception due to mock responder returning failure HRESULT.");
            }
            catch (Exception e)
            {
                Assert.IsTrue(e is AggregateException);
                Assert.IsNotNull(e.InnerException);
                Assert.IsTrue(e.InnerException is DevicePortalException);

                DevicePortalException exception = e.InnerException as DevicePortalException;

                Assert.AreEqual(-2136866553, exception.HResult);
                Assert.AreEqual("The maximum number of sponsored users is already signed in.", exception.Reason);
            }
        }
    }
}
+81 −1
Original line number Diff line number Diff line
@@ -5,13 +5,19 @@
//----------------------------------------------------------------------------------------------

using System;
using System.IO;
#if !WINDOWS_UWP
using System.Net;
using System.Net.Http;
#endif // !WINDOWS_UWP
using System.Runtime.InteropServices.WindowsRuntime;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Security;
using System.Threading.Tasks;
#if WINDOWS_UWP
using Windows.Foundation;
using Windows.Storage.Streams;
using Windows.Web.Http;
#endif // WINDOWS_UWP

@@ -37,10 +43,60 @@ namespace Microsoft.Tools.WindowsDevicePortal
            Exception innerException = null) : this(
                                                    responseMessage.StatusCode,
                                                    responseMessage.ReasonPhrase,
                                                    responseMessage.RequestMessage.RequestUri,
                                                    responseMessage.RequestMessage != null? responseMessage.RequestMessage.RequestUri : null,
                                                    message,
                                                    innerException)
        {
            try
            {
                if (responseMessage.Content != null)
                {
                    Stream dataStream = null;
#if !WINDOWS_UWP
                using (HttpContent content = responseMessage.Content)
                {
                    dataStream = new MemoryStream();

                    Task copyTask = content.CopyToAsync(dataStream);
                    copyTask.ConfigureAwait(false);
                    copyTask.Wait();

                    // Ensure we point the stream at the origin.
                    dataStream.Position = 0;
                }
#else // WINDOWS_UWP
                    IBuffer dataBuffer = null;
                    using (IHttpContent messageContent = responseMessage.Content)
                    {
                        IAsyncOperationWithProgress<IBuffer, ulong> bufferOperation = messageContent.ReadAsBufferAsync();
                        while (bufferOperation.Status != AsyncStatus.Completed)
                        {
                        }

                        dataBuffer = bufferOperation.GetResults();

                        if (dataBuffer != null)
                        {
                            dataStream = dataBuffer.AsStream();
                        }
                    }
#endif  // WINDOWS_UWP

                    if (dataStream != null)
                    {
                        DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(HttpErrorResponse));

                        HttpErrorResponse errorResponse = (HttpErrorResponse)serializer.ReadObject(dataStream);

                        this.HResult = errorResponse.ErrorCode;
                        this.Reason = errorResponse.ErrorMessage;
                    }
                }
            }
            catch (Exception)
            {
                // Do nothing if we fail to get additional error details from the response body.
            }
        }

        /// <summary>
@@ -93,5 +149,29 @@ namespace Microsoft.Tools.WindowsDevicePortal
            base.GetObjectData(info, context);
        }
#endif // !WINDOWS_UWP

        #region data contract

        /// <summary>
        /// Object containing additional error information from
        /// an HTTP response.
        /// </summary>
        [DataContract]
        private class HttpErrorResponse
        {
            /// <summary>
            /// Gets or sets the ErrorCode
            /// </summary>
            [DataMember(Name = "ErrorCode")]
            public int ErrorCode { get; set; }

            /// <summary>
            /// Gets or sets the ErrorMessage
            /// </summary>
            [DataMember(Name = "ErrorMessage")]
            public string ErrorMessage { get; set; }
        }

        #endregion
    }
}