Skip to content

Commit 221b01b

Browse files
committed
fix: enhance error handling for WebException across multiple models and add corresponding unit tests
1 parent f888bd1 commit 221b01b

File tree

14 files changed

+339
-0
lines changed

14 files changed

+339
-0
lines changed

Contentstack.Core.Unit.Tests/AssetLibraryUnitTests.cs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,40 @@ public void GetContentstackError_WithGenericException_ReturnsContentstackExcepti
549549
Assert.Equal("Test error", result.Message);
550550
}
551551

552+
[Fact]
553+
public void GetContentstackError_WithWebException_HandlesExceptionCorrectly()
554+
{
555+
// Arrange
556+
var method = typeof(AssetLibrary).GetMethod("GetContentstackError",
557+
BindingFlags.NonPublic | BindingFlags.Static);
558+
var webEx = new System.Net.WebException("Test error");
559+
560+
// Act
561+
var result = method?.Invoke(null, new object[] { webEx }) as ContentstackException;
562+
563+
// Assert
564+
Assert.NotNull(result);
565+
// When WebException has no response, it should fall back to ex.Message
566+
Assert.NotNull(result.Message);
567+
}
568+
569+
[Fact]
570+
public void ErrorHandling_WithWebException_ExtractsErrorMessage()
571+
{
572+
// Arrange
573+
var method = typeof(AssetLibrary).GetMethod("GetContentstackError",
574+
BindingFlags.NonPublic | BindingFlags.Static);
575+
var errorMessage = "Asset library error";
576+
var ex = new Exception(errorMessage);
577+
578+
// Act
579+
var result = method?.Invoke(null, new object[] { ex }) as ContentstackException;
580+
581+
// Assert
582+
Assert.NotNull(result);
583+
Assert.Equal(errorMessage, result.Message);
584+
}
585+
552586
[Fact]
553587
public void GetHeader_WithNullLocalHeader_ReturnsStackHeaders()
554588
{

Contentstack.Core.Unit.Tests/AssetUnitTests.cs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,40 @@ public void GetContentstackError_WithGenericException_ReturnsContentstackExcepti
536536
Assert.Equal("Test error", result.Message);
537537
}
538538

539+
[Fact]
540+
public void GetContentstackError_WithWebException_HandlesExceptionCorrectly()
541+
{
542+
// Arrange
543+
var method = typeof(Asset).GetMethod("GetContentstackError",
544+
BindingFlags.NonPublic | BindingFlags.Static);
545+
var webEx = new System.Net.WebException("Test error");
546+
547+
// Act
548+
var result = method?.Invoke(null, new object[] { webEx }) as ContentstackException;
549+
550+
// Assert
551+
Assert.NotNull(result);
552+
// When WebException has no response, it should fall back to ex.Message
553+
Assert.NotNull(result.Message);
554+
}
555+
556+
[Fact]
557+
public void ErrorHandling_WithWebException_ExtractsErrorMessage()
558+
{
559+
// Arrange
560+
var method = typeof(Asset).GetMethod("GetContentstackError",
561+
BindingFlags.NonPublic | BindingFlags.Static);
562+
var errorMessage = "Asset processing failed";
563+
var ex = new Exception(errorMessage);
564+
565+
// Act
566+
var result = method?.Invoke(null, new object[] { ex }) as ContentstackException;
567+
568+
// Assert
569+
Assert.NotNull(result);
570+
Assert.Equal(errorMessage, result.Message);
571+
}
572+
539573
[Fact]
540574
public void GetHeader_WithNullLocalHeader_ReturnsStackHeaders()
541575
{

Contentstack.Core.Unit.Tests/ContentTypeUnitTests.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,36 @@ public void GetContentstackError_WithGenericException_ReturnsContentstackExcepti
311311
Assert.IsType<ContentstackException>(result);
312312
}
313313

314+
[Fact]
315+
public void GetContentstackError_WithGenericException_ReturnsExceptionWithCorrectMessage()
316+
{
317+
// Arrange
318+
var errorMessage = "Content type error";
319+
var exception = new Exception(errorMessage);
320+
321+
// Act
322+
var result = ContentType.GetContentstackError(exception);
323+
324+
// Assert
325+
Assert.NotNull(result);
326+
Assert.Equal(errorMessage, result.Message);
327+
}
328+
329+
[Fact]
330+
public void GetContentstackError_WithWebException_HandlesExceptionCorrectly()
331+
{
332+
// Arrange
333+
var webEx = new System.Net.WebException("Test error");
334+
335+
// Act
336+
var result = ContentType.GetContentstackError(webEx);
337+
338+
// Assert
339+
Assert.NotNull(result);
340+
// When WebException has no response, it should fall back to ex.Message
341+
Assert.NotNull(result.Message);
342+
}
343+
314344
[Fact]
315345
public void Fetch_WithIncludeBranch_VerifiesQueryParameters()
316346
{

Contentstack.Core.Unit.Tests/EntryUnitTests.cs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1704,6 +1704,42 @@ public void GetContentstackError_WithGenericException_ReturnsContentstackExcepti
17041704
Assert.Equal("Test error", result.Message);
17051705
}
17061706

1707+
[Fact]
1708+
public void GetContentstackError_WithWebException_HandlesExceptionCorrectly()
1709+
{
1710+
// Arrange
1711+
var method = typeof(Entry).GetMethod("GetContentstackError",
1712+
BindingFlags.NonPublic | BindingFlags.Static);
1713+
var webEx = new System.Net.WebException("Test error");
1714+
1715+
// Act
1716+
var result = method?.Invoke(null, new object[] { webEx }) as ContentstackException;
1717+
1718+
// Assert
1719+
Assert.NotNull(result);
1720+
// When WebException has no response, it should fall back to ex.Message
1721+
Assert.NotNull(result.Message);
1722+
}
1723+
1724+
[Fact]
1725+
public void ErrorHandling_WithWebException_ExtractsErrorMessage()
1726+
{
1727+
// Arrange
1728+
// This test verifies that the error handling logic properly checks for WebException
1729+
// and calls GetContentstackError to extract error messages
1730+
var method = typeof(Entry).GetMethod("GetContentstackError",
1731+
BindingFlags.NonPublic | BindingFlags.Static);
1732+
var errorMessage = "Custom error message";
1733+
var ex = new Exception(errorMessage);
1734+
1735+
// Act
1736+
var result = method?.Invoke(null, new object[] { ex }) as ContentstackException;
1737+
1738+
// Assert
1739+
Assert.NotNull(result);
1740+
Assert.Equal(errorMessage, result.Message);
1741+
}
1742+
17071743
[Fact]
17081744
public void GetHeader_WithNullLocalHeader_ReturnsFormHeaders()
17091745
{

Contentstack.Core.Unit.Tests/GlobalFieldQueryUnitTests.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,36 @@ public void GetContentstackError_WithGenericException_ReturnsContentstackExcepti
142142
Assert.IsType<ContentstackException>(result);
143143
}
144144

145+
[Fact]
146+
public void GetContentstackError_WithGenericException_ReturnsExceptionWithCorrectMessage()
147+
{
148+
// Arrange
149+
var errorMessage = "Global field query error";
150+
var exception = new Exception(errorMessage);
151+
152+
// Act
153+
var result = GlobalFieldQuery.GetContentstackError(exception);
154+
155+
// Assert
156+
Assert.NotNull(result);
157+
Assert.Equal(errorMessage, result.Message);
158+
}
159+
160+
[Fact]
161+
public void GetContentstackError_WithWebException_HandlesExceptionCorrectly()
162+
{
163+
// Arrange
164+
var webEx = new System.Net.WebException("Test error");
165+
166+
// Act
167+
var result = GlobalFieldQuery.GetContentstackError(webEx);
168+
169+
// Assert
170+
Assert.NotNull(result);
171+
// When WebException has no response, it should fall back to ex.Message
172+
Assert.NotNull(result.Message);
173+
}
174+
145175
[Fact]
146176
public void Find_WithMultipleParameters_VerifiesAllQueryParameters()
147177
{

Contentstack.Core.Unit.Tests/GlobalFieldUnitTests.cs

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,75 @@ public void RemoveHeader_RemovesHeader()
138138
}
139139

140140
#endregion
141+
142+
#region GetContentstackError Tests
143+
144+
[Fact]
145+
public void GetContentstackError_WithWebException_ReturnsContentstackException()
146+
{
147+
// Arrange
148+
var method = typeof(GlobalField).GetMethod("GetContentstackError",
149+
BindingFlags.NonPublic | BindingFlags.Static);
150+
var webEx = new System.Net.WebException("Test error");
151+
152+
// Act
153+
var result = method?.Invoke(null, new object[] { webEx }) as Contentstack.Core.Internals.ContentstackException;
154+
155+
// Assert
156+
Assert.NotNull(result);
157+
}
158+
159+
[Fact]
160+
public void GetContentstackError_WithGenericException_ReturnsContentstackException()
161+
{
162+
// Arrange
163+
var method = typeof(GlobalField).GetMethod("GetContentstackError",
164+
BindingFlags.NonPublic | BindingFlags.Static);
165+
var ex = new Exception("Test error");
166+
167+
// Act
168+
var result = method?.Invoke(null, new object[] { ex }) as Contentstack.Core.Internals.ContentstackException;
169+
170+
// Assert
171+
Assert.NotNull(result);
172+
Assert.Equal("Test error", result.Message);
173+
}
174+
175+
[Fact]
176+
public void GetContentstackError_WithWebException_HandlesExceptionCorrectly()
177+
{
178+
// Arrange
179+
var method = typeof(GlobalField).GetMethod("GetContentstackError",
180+
BindingFlags.NonPublic | BindingFlags.Static);
181+
var webEx = new System.Net.WebException("Test error");
182+
183+
// Act
184+
var result = method?.Invoke(null, new object[] { webEx }) as Contentstack.Core.Internals.ContentstackException;
185+
186+
// Assert
187+
Assert.NotNull(result);
188+
// When WebException has no response, it should fall back to ex.Message
189+
Assert.NotNull(result.Message);
190+
}
191+
192+
[Fact]
193+
public void ErrorHandling_WithWebException_ExtractsErrorMessage()
194+
{
195+
// Arrange
196+
var method = typeof(GlobalField).GetMethod("GetContentstackError",
197+
BindingFlags.NonPublic | BindingFlags.Static);
198+
var errorMessage = "Global field error";
199+
var ex = new Exception(errorMessage);
200+
201+
// Act
202+
var result = method?.Invoke(null, new object[] { ex }) as Contentstack.Core.Internals.ContentstackException;
203+
204+
// Assert
205+
Assert.NotNull(result);
206+
Assert.Equal(errorMessage, result.Message);
207+
}
208+
209+
#endregion
141210
}
142211
}
143212

Contentstack.Core.Unit.Tests/QueryUnitTests.cs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1447,6 +1447,42 @@ public void GetContentstackError_WithGenericException_ReturnsContentstackExcepti
14471447
Assert.IsType<ContentstackException>(result);
14481448
}
14491449

1450+
[Fact]
1451+
public void GetContentstackError_WithGenericException_ReturnsExceptionWithCorrectMessage()
1452+
{
1453+
// Arrange
1454+
var method = typeof(Query).GetMethod("GetContentstackError",
1455+
BindingFlags.NonPublic | BindingFlags.Static);
1456+
var errorMessage = "Test error message";
1457+
var ex = new Exception(errorMessage);
1458+
1459+
// Act
1460+
var result = method?.Invoke(null, new object[] { ex }) as ContentstackException;
1461+
1462+
// Assert
1463+
Assert.NotNull(result);
1464+
Assert.Equal(errorMessage, result.Message);
1465+
}
1466+
1467+
[Fact]
1468+
public void ErrorHandling_WithWebException_CallsGetContentstackError()
1469+
{
1470+
// Arrange
1471+
// This test verifies that when a WebException is caught, GetContentstackError is called
1472+
// We can't easily mock a WebException with a response, but we can verify the logic path
1473+
var method = typeof(Query).GetMethod("GetContentstackError",
1474+
BindingFlags.NonPublic | BindingFlags.Static);
1475+
var webEx = new System.Net.WebException("Test error");
1476+
1477+
// Act
1478+
var result = method?.Invoke(null, new object[] { webEx }) as ContentstackException;
1479+
1480+
// Assert
1481+
Assert.NotNull(result);
1482+
// When WebException has no response, it should fall back to ex.Message
1483+
Assert.NotNull(result.Message);
1484+
}
1485+
14501486
[Fact]
14511487
public void And_WithExistingAndKey_ReplacesAndValue()
14521488
{

Contentstack.Core/Models/Asset.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,16 @@ public async Task<Asset> Fetch()
424424
}
425425
catch (Exception ex)
426426
{
427+
if (ex is System.Net.WebException)
428+
{
429+
var contentstackError = GetContentstackError(ex);
430+
throw new AssetException(contentstackError.Message, ex)
431+
{
432+
ErrorCode = contentstackError.ErrorCode,
433+
StatusCode = contentstackError.StatusCode,
434+
Errors = contentstackError.Errors
435+
};
436+
}
427437
throw AssetException.CreateForProcessingError(ex);
428438
}
429439
}

Contentstack.Core/Models/AssetLibrary.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,16 @@ private async Task<JObject> Exec()
580580
}
581581
catch (Exception ex)
582582
{
583+
if (ex is System.Net.WebException)
584+
{
585+
var contentstackError = GetContentstackError(ex);
586+
throw new AssetException(contentstackError.Message, ex)
587+
{
588+
ErrorCode = contentstackError.ErrorCode,
589+
StatusCode = contentstackError.StatusCode,
590+
Errors = contentstackError.Errors
591+
};
592+
}
583593
throw AssetException.CreateForProcessingError(ex);
584594
}
585595
}

Contentstack.Core/Models/ContentType.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,16 @@ public async Task<JObject> Fetch(Dictionary<string, object> param = null)
175175
}
176176
catch (Exception ex)
177177
{
178+
if (ex is System.Net.WebException)
179+
{
180+
var contentstackError = GetContentstackError(ex);
181+
throw new ContentTypeException(contentstackError.Message, ex)
182+
{
183+
ErrorCode = contentstackError.ErrorCode,
184+
StatusCode = contentstackError.StatusCode,
185+
Errors = contentstackError.Errors
186+
};
187+
}
178188
throw ContentTypeException.CreateForProcessingError(ex);
179189
}
180190
}

0 commit comments

Comments
 (0)