diff --git a/src/client/Microsoft.Identity.Client/MsalServiceException.cs b/src/client/Microsoft.Identity.Client/MsalServiceException.cs index e3bdb484dc..116eb02bd1 100644 --- a/src/client/Microsoft.Identity.Client/MsalServiceException.cs +++ b/src/client/Microsoft.Identity.Client/MsalServiceException.cs @@ -242,10 +242,9 @@ public override string ToString() { return base.ToString() + string.Format( CultureInfo.InvariantCulture, - "\n\tStatusCode: {0} \n\tResponseBody: {1} \n\tHeaders: {2}", + "\n\tStatusCode: {0} \n\tResponseBody: {1}", StatusCode, - ResponseBody, - Headers); + ResponseBody); } #region Serialization diff --git a/tests/Microsoft.Identity.Test.Unit/ExceptionTests/MsalExceptionTests.cs b/tests/Microsoft.Identity.Test.Unit/ExceptionTests/MsalExceptionTests.cs index 9accbc44be..f8176ac7b2 100644 --- a/tests/Microsoft.Identity.Test.Unit/ExceptionTests/MsalExceptionTests.cs +++ b/tests/Microsoft.Identity.Test.Unit/ExceptionTests/MsalExceptionTests.cs @@ -429,6 +429,41 @@ public void ServiceException_ToString() ValidateExceptionProductInformation(ex); } + [TestMethod] + public void ServiceException_ToString_DoesNotIncludeHeaders() + { + // Arrange + const string jsonError = @"{ ""error"":""invalid_grant"", + ""error_description"":""Error description""}"; + + var httpResponseMessage = new HttpResponseMessage(HttpStatusCode.BadRequest) + { + Content = new StringContent(jsonError) + }; + httpResponseMessage.Headers.Add("X-Custom-Header", "SensitiveValue"); + httpResponseMessage.Headers.RetryAfter = new RetryConditionHeaderValue(TimeSpan.FromSeconds(120)); + + HttpResponse httpResponse = HttpManager.CreateResponseAsync(httpResponseMessage).Result; + + // Act + var ex = MsalServiceExceptionFactory.FromHttpResponse("errCode", "errMessage", httpResponse); + string exceptionString = ex.ToString(); + + // Assert - Headers should NOT be in ToString() + Assert.IsFalse(exceptionString.Contains("X-Custom-Header"), "Headers should not be included in ToString()"); + Assert.IsFalse(exceptionString.Contains("SensitiveValue"), "Header values should not be included in ToString()"); + Assert.IsFalse(exceptionString.Contains("RetryAfter"), "RetryAfter header should not be included in ToString()"); + + // Assert - Headers property should still be accessible + Assert.IsNotNull(ex.Headers, "Headers property should still be accessible"); + Assert.IsNotNull(ex.Headers.RetryAfter, "RetryAfter header should be accessible via Headers property"); + Assert.AreEqual(TimeSpan.FromSeconds(120), ex.Headers.RetryAfter.Delta, "RetryAfter value should be preserved"); + + // Assert - Other information should still be in ToString() + Assert.IsTrue(exceptionString.Contains("errCode"), "Error code should be in ToString()"); + Assert.IsTrue(exceptionString.Contains("StatusCode"), "Status code label should be in ToString()"); + } + [TestMethod] public void ExceptionsPropertiesHavePublicSetters() {