Skip to content

Commit 3e51f35

Browse files
committed
Refactor error handling in asset and entry processing to use custom exceptions for improved clarity and maintainability.
1 parent fc4eae2 commit 3e51f35

9 files changed

Lines changed: 241 additions & 50 deletions

File tree

Contentstack.Core/Internals/AssetJsonConverter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public override Asset ReadJson(JsonReader reader, Type objectType, Asset existin
2020

2121
public override void WriteJson(JsonWriter writer, Asset value, JsonSerializer serializer)
2222
{
23-
throw new NotImplementedException("Failed to convert asset JSON. Please check the asset format and data integrity.");
23+
throw AssetException.CreateForJsonConversionError();
2424
}
2525
}
2626
}
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Net;
4+
5+
namespace Contentstack.Core.Internals
6+
{
7+
/// <summary>
8+
/// Base exception class for all Contentstack exceptions
9+
/// </summary>
10+
public class ContentstackException : Exception
11+
{
12+
public int ErrorCode { get; set; }
13+
public HttpStatusCode StatusCode { get; set; }
14+
public Dictionary<string, object> Errors { get; set; }
15+
16+
public ContentstackException() : base()
17+
{
18+
}
19+
20+
public ContentstackException(string message) : base(message)
21+
{
22+
}
23+
24+
public ContentstackException(string message, Exception innerException) : base(message, innerException)
25+
{
26+
}
27+
28+
public ContentstackException(Exception ex) : base(ex.Message, ex)
29+
{
30+
}
31+
}
32+
33+
/// <summary>
34+
/// Exception thrown when there are issues with query filters or parameters
35+
/// </summary>
36+
public class QueryFilterException : ContentstackException
37+
{
38+
public QueryFilterException() : base(ErrorMessages.QueryFilterError)
39+
{
40+
}
41+
42+
public QueryFilterException(string message) : base(message)
43+
{
44+
}
45+
46+
public QueryFilterException(string message, Exception innerException) : base(message, innerException)
47+
{
48+
}
49+
50+
public static QueryFilterException Create(Exception innerException = null)
51+
{
52+
return new QueryFilterException(
53+
string.Format(ErrorMessages.InvalidParamsError,
54+
innerException?.Message ?? ErrorMessages.QueryFilterError),
55+
innerException);
56+
}
57+
}
58+
59+
/// <summary>
60+
/// Exception thrown when there are asset-related errors
61+
/// </summary>
62+
public class AssetException : ContentstackException
63+
{
64+
public AssetException(string message) : base(message)
65+
{
66+
}
67+
68+
public AssetException(string message, Exception innerException) : base(message, innerException)
69+
{
70+
}
71+
72+
public static AssetException CreateForJsonConversionError()
73+
{
74+
return new AssetException(ErrorMessages.AssetJsonConversionError);
75+
}
76+
77+
public static AssetException CreateForProcessingError(Exception innerException)
78+
{
79+
return new AssetException(
80+
string.Format(ErrorMessages.AssetProcessingError,
81+
ErrorMessages.FormatExceptionDetails(innerException)),
82+
innerException);
83+
}
84+
}
85+
86+
/// <summary>
87+
/// Exception thrown when there are live preview-related errors
88+
/// </summary>
89+
public class LivePreviewException : ContentstackException
90+
{
91+
public LivePreviewException() : base(ErrorMessages.LivePreviewTokenMissing)
92+
{
93+
}
94+
95+
public LivePreviewException(string message) : base(message)
96+
{
97+
}
98+
99+
public LivePreviewException(string message, Exception innerException) : base(message, innerException)
100+
{
101+
}
102+
}
103+
104+
/// <summary>
105+
/// Exception thrown when there are global field-related errors
106+
/// </summary>
107+
public class GlobalFieldException : ContentstackException
108+
{
109+
public GlobalFieldException(string message) : base(message)
110+
{
111+
}
112+
113+
public GlobalFieldException(string message, Exception innerException) : base(message, innerException)
114+
{
115+
}
116+
117+
public static GlobalFieldException CreateForProcessingError(Exception innerException)
118+
{
119+
return new GlobalFieldException(
120+
string.Format(ErrorMessages.GlobalFieldProcessingError,
121+
ErrorMessages.FormatExceptionDetails(innerException)),
122+
innerException);
123+
}
124+
125+
public static GlobalFieldException CreateForIdNull()
126+
{
127+
return new GlobalFieldException(ErrorMessages.GlobalFieldIdNullError);
128+
}
129+
}
130+
131+
/// <summary>
132+
/// Exception thrown when there are entry-related errors
133+
/// </summary>
134+
public class EntryException : ContentstackException
135+
{
136+
public EntryException(string message) : base(message)
137+
{
138+
}
139+
140+
public EntryException(string message, Exception innerException) : base(message, innerException)
141+
{
142+
}
143+
144+
public static EntryException CreateForProcessingError(Exception innerException)
145+
{
146+
return new EntryException(
147+
string.Format(ErrorMessages.EntryProcessingError,
148+
ErrorMessages.FormatExceptionDetails(innerException)),
149+
innerException);
150+
}
151+
}
152+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
using System;
2+
3+
namespace Contentstack.Core.Internals
4+
{
5+
/// <summary>
6+
/// Contains all error message constants used throughout the SDK
7+
/// </summary>
8+
internal static class ErrorMessages
9+
{
10+
// Query and Filter related errors
11+
public const string QueryFilterError = "Please provide valid params.";
12+
public const string InvalidParamsError = "Invalid parameters provided. {0}";
13+
14+
// Asset related errors
15+
public const string AssetJsonConversionError = "Failed to convert asset JSON. Please check the asset format and data integrity.";
16+
public const string AssetProcessingError = "An error occurred while processing the asset. {0}";
17+
public const string AssetLibraryRequestError = "Exception in {0}: {1}\nStackTrace: {2}";
18+
19+
// Entry related errors
20+
public const string EntryProcessingError = "An error occurred while processing the entry. {0}";
21+
22+
// Global Field related errors
23+
public const string GlobalFieldIdNullError = "GlobalFieldId required. This value cannot be null or empty, define it in your configuration.";
24+
public const string GlobalFieldProcessingError = "An error occurred while processing the globalField. {0}";
25+
public const string GlobalFieldQueryError = "Global field query failed. Check your query syntax and field schema before retrying.";
26+
27+
// Live Preview related errors
28+
public const string LivePreviewTokenMissing = "Live Preview token missing. Add either a PreviewToken or a ManagementToken in the LivePreviewConfig.";
29+
30+
// Helper method to format exception details
31+
public static string FormatExceptionDetails(Exception ex)
32+
{
33+
return string.Format("Exception: {0}\nSource: {1}\nStackTrace: {2}",
34+
ex.Message,
35+
ex.Source ?? "Unknown",
36+
ex.StackTrace ?? "No stack trace available");
37+
}
38+
}
39+
}

Contentstack.Core/Models/Asset.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ public object this[string key]
6464
{
6565
if (e.Source != null)
6666
{
67-
Console.WriteLine($"Exception: {e.Message}\nSource: {e.Source ?? "Unknown"}\nStackTrace: {e.StackTrace ?? "No stack trace available"}");
67+
Console.WriteLine(ErrorMessages.FormatExceptionDetails(e));
6868
}
6969
}
7070
}
@@ -424,7 +424,7 @@ public async Task<Asset> Fetch()
424424
}
425425
catch (Exception ex)
426426
{
427-
throw new ContentstackException("Unable to process asset. Ensure the file format, size, and encoding meet the required standards.", ex);
427+
throw new ContentstackException(string.Format(ErrorMessages.AssetProcessingError, ErrorMessages.FormatExceptionDetails(ex)));
428428
}
429429
}
430430

Contentstack.Core/Models/AssetLibrary.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -508,7 +508,7 @@ private async Task<JObject> Exec()
508508
}
509509
catch (Exception ex)
510510
{
511-
throw new ContentstackException($"Exception in {ex.GetType().Name}: {ex.Message}\nStackTrace: {ex.StackTrace}");
511+
throw AssetException.CreateForProcessingError(ex);
512512
}
513513
}
514514
#endregion

Contentstack.Core/Models/Entry.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1405,7 +1405,7 @@ public async Task<T> Fetch<T>()
14051405
} else if (!string.IsNullOrEmpty(this.ContentTypeInstance.StackInstance.LivePreviewConfig.PreviewToken)) {
14061406
headerAll["preview_token"] = this.ContentTypeInstance.StackInstance.LivePreviewConfig.PreviewToken;
14071407
} else {
1408-
throw new InvalidOperationException("Live Preview token missing. Add either a PreviewToken or a ManagementToken in the LivePreviewConfig.");
1408+
throw new LivePreviewException();
14091409
}
14101410

14111411
if (!string.IsNullOrEmpty(this.ContentTypeInstance.StackInstance.LivePreviewConfig.ReleaseId))
@@ -1446,7 +1446,7 @@ public async Task<T> Fetch<T>()
14461446
}
14471447
catch (Exception ex)
14481448
{
1449-
throw new ContentstackException("An error occurred while processing the entry "+ $"Exception: {ex.Message}\nSource: {ex.Source ?? "Unknown"}\nStackTrace: {ex.StackTrace ?? "No stack trace available"}");
1449+
throw EntryException.CreateForProcessingError(ex);
14501450
}
14511451
}
14521452

Contentstack.Core/Models/GlobalField.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public string GlobalFieldId
3333
set
3434
{
3535
if (String.IsNullOrEmpty(value))
36-
throw new ArgumentNullException("GlobalFieldId required. This value cannot be null or empty, define it in your configuration.");
36+
throw GlobalFieldException.CreateForIdNull();
3737
this.Uid = value;
3838
}
3939
}
@@ -189,7 +189,7 @@ public async Task<JObject> Fetch(Dictionary<string, object> param = null)
189189
}
190190
catch (Exception ex)
191191
{
192-
throw new ContentstackException("An error occurred while processing the globalField. "+$"Exception: {ex.Message}\nSource: {ex.Source ?? "Unknown"}\nStackTrace: {ex.StackTrace ?? "No stack trace available"}");
192+
throw GlobalFieldException.CreateForProcessingError(ex);
193193
}
194194
}
195195

Contentstack.Core/Models/GlobalFieldQuery.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ public async Task<JObject> Find(Dictionary<string, object> param = null)
157157
}
158158
catch (Exception ex)
159159
{
160-
throw new ContentstackException("Global field query failed. Check your query syntax and field schema before retrying.", ex);
160+
throw new ContentstackException(ErrorMessages.GlobalFieldQueryError, ex);
161161
}
162162
}
163163

0 commit comments

Comments
 (0)