Skip to content

Commit 2c09b8b

Browse files
[Service Bus] Fix error parsing logic (Azure#48156)
* [Service Bus] Fix error parsing logic The focus of these changes is to fix the logic for parsing error codes from the Service Bus administration service. The implementation assumes that all error responses will have a content body, which is not always the case. For example, an HTTP 401 is returned without a body. In this scenario, the error detail parsing faults and surfaces an exception, obscuring the original 401 status code. * Adding changelog * Update sdk/servicebus/Azure.Messaging.ServiceBus/src/Administration/ServiceBusRequestFailedDetailsParser.cs Co-authored-by: JoshLove-msft <[email protected]> --------- Co-authored-by: JoshLove-msft <[email protected]>
1 parent 8e6b16f commit 2c09b8b

File tree

3 files changed

+80
-1
lines changed

3 files changed

+80
-1
lines changed

sdk/servicebus/Azure.Messaging.ServiceBus/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
### Bugs Fixed
1010

11+
- Fixed an issue where an error response from the Service Bus administration service without a body was incorrectly parsed, resulting in a null argument exception obscuring the actual failure response. ([#47517](https://github.com/Azure/azure-sdk-for-net/issues/47517))
12+
1113
### Other Changes
1214

1315
## 7.18.3 (2025-01-17)

sdk/servicebus/Azure.Messaging.ServiceBus/src/Administration/ServiceBusRequestFailedDetailsParser.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ internal sealed class ServiceBusRequestFailedDetailsParser : RequestFailedDetail
1515
public override bool TryParse(Response response, out ResponseError? error, out IDictionary<string, string>? data)
1616
{
1717
data = default;
18-
if (response.ContentStream is { CanSeek: true })
18+
if (response.ContentStream is { CanSeek: true, Length: > 0})
1919
{
2020
var position = response.ContentStream.Position;
2121
try
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
using System;
5+
using System.IO;
6+
using Azure.Core.Pipeline;
7+
using Azure.Core.TestFramework;
8+
using Moq;
9+
using NUnit.Framework;
10+
11+
namespace Azure.Messaging.ServiceBus.Tests.Administration
12+
{
13+
[TestFixture]
14+
public class ServiceBusRequestFailedDetailsParserTests
15+
{
16+
[Test]
17+
public void ZeroLengthStreamReturnsDefaultErrorDetails()
18+
{
19+
var response = new MockResponse(401);
20+
response.SetIsError(true);
21+
response.SetContent(Array.Empty<byte>());
22+
23+
var parser = new ServiceBusRequestFailedDetailsParser();
24+
parser.TryParse(response, out var error, out var data);
25+
26+
Assert.AreSame(default(ResponseError), error);
27+
}
28+
29+
[Test]
30+
public void NonSeekingStreamReturnsDefaultErrorDetails()
31+
{
32+
var mockStream = new Mock<Stream>();
33+
var response = new MockResponse(401) { ContentStream = mockStream.Object };
34+
35+
mockStream
36+
.Setup(stream => stream.CanSeek)
37+
.Returns(false);
38+
39+
mockStream
40+
.Setup(stream => stream.Length)
41+
.Returns(1);
42+
43+
response.SetIsError(true);
44+
45+
var parser = new ServiceBusRequestFailedDetailsParser();
46+
parser.TryParse(response, out var error, out var data);
47+
48+
Assert.AreSame(default(ResponseError), error);
49+
}
50+
51+
[Test]
52+
public void XmlBodyReturnsErrorDetails()
53+
{
54+
var subcCode = "40100";
55+
var message = $"SubCode={subcCode}. Failed to authenticate";
56+
57+
var errorContent =
58+
@$"<?xml version=""1.0"" encoding=""UTF-8""?>
59+
<Error>
60+
<Code>401</Code>
61+
<Detail>{message}</Detail>
62+
</Error>";
63+
64+
var response = new MockResponse(401);
65+
response.SetIsError(true);
66+
response.SetContent(errorContent);
67+
68+
var parser = new ServiceBusRequestFailedDetailsParser();
69+
parser.TryParse(response, out var error, out var data);
70+
71+
Assert.NotNull(error);
72+
Assert.AreNotSame(error, default(ResponseError));
73+
Assert.AreEqual(subcCode, error.Code);
74+
Assert.AreEqual(message, error.Message);
75+
}
76+
}
77+
}

0 commit comments

Comments
 (0)