diff --git a/docs/generators/csharp.md b/docs/generators/csharp.md
index b490fa6fe1d3..eb6fcdf5df13 100644
--- a/docs/generators/csharp.md
+++ b/docs/generators/csharp.md
@@ -47,6 +47,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|returnICollection|Return ICollection<T> instead of the concrete type.| |false|
|sourceFolder|source folder for generated code| |src|
|targetFramework|The target .NET framework version. To target multiple frameworks, use `;` as the separator, e.g. `netstandard2.1;netcoreapp3.1`|
- **netstandard1.3**
- .NET Standard 1.3
- **netstandard1.4**
- .NET Standard 1.4
- **netstandard1.5**
- .NET Standard 1.5
- **netstandard1.6**
- .NET Standard 1.6
- **netstandard2.0**
- .NET Standard 2.0
- **netstandard2.1**
- .NET Standard 2.1
- **net47**
- .NET Framework 4.7
- **net48**
- .NET Framework 4.8
- **net8.0**
- .NET 8.0 (End of Support 10 November 2026)
- **net9.0**
- .NET 9.0 (End of Support 10 November 2026)
- **net10.0**
- .NET 10.0 (End of Support 14 November 2028)
|net10.0|
+|throwOnAnyError|Configure RestSharp to rethrow deserialization and transport errors instead of swallowing them into RestResponse.ErrorException (which the default ToApiResponse<T> discards as null Data). Recommended for production use to surface bugs that would otherwise be invisible. (restsharp only)| |false|
|useCollection|Deserialize array types to Collection<T> instead of List<T>.| |false|
|useDateTimeForDate|Use DateTime to model date properties even if DateOnly supported. (.net 6.0+ only)| |false|
|useDateTimeOffset|Use DateTimeOffset to model date-time properties| |false|
diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/CSharpClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/CSharpClientCodegen.java
index 466167194012..72c1fdf0921c 100644
--- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/CSharpClientCodegen.java
+++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/CSharpClientCodegen.java
@@ -122,6 +122,7 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
protected boolean supportsFileParameters = Boolean.TRUE;
protected boolean supportsDateOnly = Boolean.FALSE;
protected boolean useIntForTimeout = Boolean.FALSE;
+ protected boolean throwOnAnyError = Boolean.FALSE;
@Setter protected boolean validatable = Boolean.TRUE;
@Setter protected boolean equatable = Boolean.FALSE;
@@ -132,6 +133,7 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
private static final String OPERATION_PARAMETER_SORTING_KEY = "operationParameterSorting";
private static final String MODEL_PROPERTY_SORTING_KEY = "modelPropertySorting";
private static final String USE_INT_FOR_TIMEOUT = "useIntForTimeout";
+ private static final String THROW_ON_ANY_ERROR = "throwOnAnyError";
enum SortingMethod {
DEFAULT,
@@ -249,6 +251,10 @@ public CSharpClientCodegen() {
"Use int for Timeout (fall back to v7.9.0 templates). This option (for restsharp only) will be deprecated so please migrated to TimeSpan instead.",
String.valueOf(this.useIntForTimeout));
+ addSwitch(CSharpClientCodegen.THROW_ON_ANY_ERROR,
+ "Configure RestSharp to rethrow deserialization and transport errors instead of swallowing them into RestResponse.ErrorException (which the default ToApiResponse discards as null Data). Recommended for production use to surface bugs that would otherwise be invisible. (restsharp only)",
+ this.throwOnAnyError);
+
CliOption framework = new CliOption(
CodegenConstants.DOTNET_FRAMEWORK,
CodegenConstants.DOTNET_FRAMEWORK_DESC
@@ -871,6 +877,7 @@ public void processOpts() {
syncBooleanProperty(additionalProperties, "useSourceGeneration", this::setUseSourceGeneration, this.useSourceGeneration);
syncBooleanProperty(additionalProperties, "supportsDateOnly", this::setSupportsDateOnly, this.supportsDateOnly);
syncBooleanProperty(additionalProperties, "useIntForTimeout", this::setUseIntForTimeout, this.useIntForTimeout);
+ syncBooleanProperty(additionalProperties, "throwOnAnyError", this::setThrowOnAnyError, this.throwOnAnyError);
final String testPackageName = testPackageName();
String packageFolder = sourceFolder + File.separator + packageName;
@@ -1244,6 +1251,10 @@ public void setUseIntForTimeout(Boolean useIntForTimeout) {
this.useIntForTimeout = useIntForTimeout;
}
+ public void setThrowOnAnyError(Boolean throwOnAnyError) {
+ this.throwOnAnyError = throwOnAnyError;
+ }
+
public void setSupportsRetry(Boolean supportsRetry) {
this.supportsRetry = supportsRetry;
}
diff --git a/modules/openapi-generator/src/main/resources/csharp/ApiClient.mustache b/modules/openapi-generator/src/main/resources/csharp/ApiClient.mustache
index 3e774675356f..d1946b37a38f 100644
--- a/modules/openapi-generator/src/main/resources/csharp/ApiClient.mustache
+++ b/modules/openapi-generator/src/main/resources/csharp/ApiClient.mustache
@@ -467,7 +467,8 @@ namespace {{packageName}}.Client
Proxy = configuration.Proxy,
UserAgent = configuration.UserAgent,
UseDefaultCredentials = configuration.UseDefaultCredentials,
- RemoteCertificateValidationCallback = configuration.RemoteCertificateValidationCallback
+ RemoteCertificateValidationCallback = configuration.RemoteCertificateValidationCallback{{#throwOnAnyError}},
+ ThrowOnAnyError = true{{/throwOnAnyError}}
};
setOptions(clientOptions);
@@ -566,10 +567,15 @@ namespace {{packageName}}.Client
}
else
{
+ {{#throwOnAnyError}}
+ throw policyResult.FinalException ?? new InvalidOperationException("The retry policy failed without an exception.");
+ {{/throwOnAnyError}}
+ {{^throwOnAnyError}}
return new RestResponse(request)
{
ErrorException = policyResult.FinalException
};
+ {{/throwOnAnyError}}
}
}
diff --git a/modules/openapi-generator/src/main/resources/csharp/ApiClient.v790.mustache b/modules/openapi-generator/src/main/resources/csharp/ApiClient.v790.mustache
index 682b762511b8..6eb294e1aec0 100644
--- a/modules/openapi-generator/src/main/resources/csharp/ApiClient.v790.mustache
+++ b/modules/openapi-generator/src/main/resources/csharp/ApiClient.v790.mustache
@@ -558,10 +558,15 @@ namespace {{packageName}}.Client
}
else
{
+ {{#throwOnAnyError}}
+ throw policyResult.FinalException ?? new InvalidOperationException("The retry policy failed without an exception.");
+ {{/throwOnAnyError}}
+ {{^throwOnAnyError}}
return new RestResponse(request)
{
ErrorException = policyResult.FinalException
};
+ {{/throwOnAnyError}}
}
}