Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
### Version: 2.25.2
#### Date: Nov-13-2025



### Version: 2.25.1
#### Date: Nov-10-2025

##### Enh:
- Improved Error messages
##### Fix:
- Taxonomy
- Fixed NullReferenceExceptions
- Fixed InvalidCastException in `GetContentstackError` when exception is not a WebException
- Fixed JsonReaderException in `GetContentstackError` when response is not valid JSON
- All exceptions now properly throw TaxonomyException (extends ContentstackException) with descriptive error messages

### Version: 2.25.0
#### Date: Jan-07-2025
Expand Down
79 changes: 60 additions & 19 deletions Contentstack.Core/Models/Taxonomy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,20 @@
{
get
{
if (this.Stack == null)
{
throw new TaxonomyException("Taxonomy Stack instance is null. Please ensure the Taxonomy is properly initialized with a ContentstackClient instance.");
}
if (this.Stack.Config == null)
{
throw new TaxonomyException("Taxonomy Stack Config is null. Please ensure the ContentstackClient is properly configured.");
}
Config config = this.Stack.Config;
return String.Format("{0}/taxonomies/entries", config.BaseUrl);
}
}
#endregion
public ContentstackClient Stack

Check warning on line 37 in Contentstack.Core/Models/Taxonomy.cs

View workflow job for this annotation

GitHub Actions / unit-test

'Taxonomy.Stack' hides inherited member 'Query.Stack'. Use the new keyword if hiding was intended.

Check warning on line 37 in Contentstack.Core/Models/Taxonomy.cs

View workflow job for this annotation

GitHub Actions / unit-test

'Taxonomy.Stack' hides inherited member 'Query.Stack'. Use the new keyword if hiding was intended.

Check warning on line 37 in Contentstack.Core/Models/Taxonomy.cs

View workflow job for this annotation

GitHub Actions / unit-test

'Taxonomy.Stack' hides inherited member 'Query.Stack'. Use the new keyword if hiding was intended.

Check warning on line 37 in Contentstack.Core/Models/Taxonomy.cs

View workflow job for this annotation

GitHub Actions / unit-test

'Taxonomy.Stack' hides inherited member 'Query.Stack'. Use the new keyword if hiding was intended.

Check warning on line 37 in Contentstack.Core/Models/Taxonomy.cs

View workflow job for this annotation

GitHub Actions / unit-test

'Taxonomy.Stack' hides inherited member 'Query.Stack'. Use the new keyword if hiding was intended.

Check warning on line 37 in Contentstack.Core/Models/Taxonomy.cs

View workflow job for this annotation

GitHub Actions / unit-test

'Taxonomy.Stack' hides inherited member 'Query.Stack'. Use the new keyword if hiding was intended.
{
get;
set;
Expand All @@ -40,6 +48,10 @@
}
internal Taxonomy(ContentstackClient stack): base(stack)
{
if (stack == null)
{
throw new TaxonomyException("ContentstackClient instance cannot be null when creating a Taxonomy instance.");
}
this.Stack = stack;
this._StackHeaders = stack._LocalHeaders;
}
Expand Down Expand Up @@ -242,7 +254,7 @@
return _StackHeaders;
}
}
internal static ContentstackException GetContentstackError(Exception ex)

Check warning on line 257 in Contentstack.Core/Models/Taxonomy.cs

View workflow job for this annotation

GitHub Actions / unit-test

'Taxonomy.GetContentstackError(Exception)' hides inherited member 'Query.GetContentstackError(Exception)'. Use the new keyword if hiding was intended.

Check warning on line 257 in Contentstack.Core/Models/Taxonomy.cs

View workflow job for this annotation

GitHub Actions / unit-test

'Taxonomy.GetContentstackError(Exception)' hides inherited member 'Query.GetContentstackError(Exception)'. Use the new keyword if hiding was intended.

Check warning on line 257 in Contentstack.Core/Models/Taxonomy.cs

View workflow job for this annotation

GitHub Actions / unit-test

'Taxonomy.GetContentstackError(Exception)' hides inherited member 'Query.GetContentstackError(Exception)'. Use the new keyword if hiding was intended.

Check warning on line 257 in Contentstack.Core/Models/Taxonomy.cs

View workflow job for this annotation

GitHub Actions / unit-test

'Taxonomy.GetContentstackError(Exception)' hides inherited member 'Query.GetContentstackError(Exception)'. Use the new keyword if hiding was intended.

Check warning on line 257 in Contentstack.Core/Models/Taxonomy.cs

View workflow job for this annotation

GitHub Actions / unit-test

'Taxonomy.GetContentstackError(Exception)' hides inherited member 'Query.GetContentstackError(Exception)'. Use the new keyword if hiding was intended.

Check warning on line 257 in Contentstack.Core/Models/Taxonomy.cs

View workflow job for this annotation

GitHub Actions / unit-test

'Taxonomy.GetContentstackError(Exception)' hides inherited member 'Query.GetContentstackError(Exception)'. Use the new keyword if hiding was intended.
{
Int32 errorCode = 0;
string errorMessage = string.Empty;
Expand All @@ -252,30 +264,59 @@

try
{
System.Net.WebException webEx = (System.Net.WebException)ex;

using (var exResp = webEx.Response)
using (var stream = exResp.GetResponseStream())
using (var reader = new StreamReader(stream))
System.Net.WebException webEx = ex as System.Net.WebException;

if (webEx != null && webEx.Response != null)
{
errorMessage = reader.ReadToEnd();
JObject data = JObject.Parse(errorMessage.Replace("\r\n", ""));
using (var exResp = webEx.Response)
{
var stream = exResp.GetResponseStream();
if (stream != null)
{
using (stream)
using (var reader = new StreamReader(stream))
{
errorMessage = reader.ReadToEnd();

if (!string.IsNullOrWhiteSpace(errorMessage))
{
try
{
JObject data = JObject.Parse(errorMessage.Replace("\r\n", ""));

JToken token = data["error_code"];
if (token != null)
errorCode = token.Value<int>();
JToken token = data["error_code"];
if (token != null)
errorCode = token.Value<int>();

token = data["error_message"];
if (token != null)
errorMessage = token.Value<string>();
token = data["error_message"];
if (token != null)
errorMessage = token.Value<string>();

token = data["errors"];
if (token != null)
errors = token.ToObject<Dictionary<string, object>>();
token = data["errors"];
if (token != null)
errors = token.ToObject<Dictionary<string, object>>();
}
catch (Newtonsoft.Json.JsonException)
{
// If JSON parsing fails, use the raw error message
// errorMessage is already set from ReadToEnd()
}
}

var response = exResp as HttpWebResponse;
if (response != null)
statusCode = response.StatusCode;
var response = exResp as HttpWebResponse;
if (response != null)
statusCode = response.StatusCode;
}
}
else
{
errorMessage = webEx.Message;
}
}
}
else
{
errorMessage = ex.Message;
}
}
catch
Expand Down
Loading