Skip to content

Commit c143937

Browse files
authored
Merge pull request #2986 from jimschubert/cs/exception_factory
[csharp] Intercept hooks for req/res and ExceptionFactory
2 parents ffc9ed1 + fafcd33 commit c143937

File tree

5 files changed

+72
-10
lines changed

5 files changed

+72
-10
lines changed

modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/CSharpClientCodegen.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,8 @@ public void processOpts() {
233233
clientPackageDir, "ApiException.cs"));
234234
supportingFiles.add(new SupportingFile("ApiResponse.mustache",
235235
clientPackageDir, "ApiResponse.cs"));
236+
supportingFiles.add(new SupportingFile("ExceptionFactory.mustache",
237+
clientPackageDir, "ExceptionFactory.cs"));
236238

237239
supportingFiles.add(new SupportingFile("compile.mustache", "", "build.bat"));
238240
supportingFiles.add(new SupportingFile("compile-mono.sh.mustache", "", "build.sh"));

modules/swagger-codegen/src/main/resources/csharp/ApiClient.mustache

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,28 @@ using RestSharp;
1717
namespace {{packageName}}.Client
1818
{
1919
/// <summary>
20-
/// API client is mainly responible for making the HTTP call to the API backend.
20+
/// API client is mainly responsible for making the HTTP call to the API backend.
2121
/// </summary>
22-
public class ApiClient
22+
public partial class ApiClient
2323
{
2424
private JsonSerializerSettings serializerSettings = new JsonSerializerSettings
2525
{
2626
ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor
2727
};
2828

29+
/// <summary>
30+
/// Allows for extending request processing for <see cref="ApiClient"/> generated code.
31+
/// </summary>
32+
/// <param name="request">The RestSharp request object</param>
33+
partial void InterceptRequest(IRestRequest request);
34+
35+
/// <summary>
36+
/// Allows for extending response processing for <see cref="ApiClient"/> generated code.
37+
/// </summary>
38+
/// <param name="request">The RestSharp request object</param>
39+
/// <param name="response">The RestSharp response object</param>
40+
partial void InterceptResponse(IRestRequest request, IRestResponse response);
41+
2942
/// <summary>
3043
/// Initializes a new instance of the <see cref="ApiClient" /> class
3144
/// with default configuration and base path ({{basePath}}).
@@ -165,13 +178,16 @@ namespace {{packageName}}.Client
165178
// set user agent
166179
RestClient.UserAgent = Configuration.UserAgent;
167180
181+
InterceptRequest(request);
168182
{{^supportsUWP}}
169183
var response = RestClient.Execute(request);
170184
{{/supportsUWP}}
171185
{{#supportsUWP}}
172186
// Using async method to perform sync call (uwp-only)
173187
var response = RestClient.ExecuteTaskAsync(request).Result;
174188
{{/supportsUWP}}
189+
InterceptResponse(request, response);
190+
175191
return (Object) response;
176192
}
177193
{{#supportsAsync}}
@@ -197,7 +213,9 @@ namespace {{packageName}}.Client
197213
var request = PrepareRequest(
198214
path, method, queryParams, postBody, headerParams, formParams, fileParams,
199215
pathParams, contentType);
216+
InterceptRequest(request);
200217
var response = await RestClient.ExecuteTaskAsync(request);
218+
InterceptResponse(request, response);
201219
return (Object)response;
202220
}{{/supportsAsync}}
203221

modules/swagger-codegen/src/main/resources/csharp/Configuration.mustache

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,17 @@ namespace {{packageName}}.Client
8080
/// <value>Configuration.</value>
8181
public static Configuration Default = new Configuration();
8282

83+
/// <summary>
84+
/// Default creation of exceptions for a given method name and response object
85+
/// </summary>
86+
public static readonly ExceptionFactory DefaultExceptionFactory = (methodName, response) =>
87+
{
88+
int status = (int) response.StatusCode;
89+
if (status >= 400) return new ApiException(status, String.Format("Error calling {0}: {1}", methodName, response.Content), response.Content);
90+
if (status == 0) return new ApiException(status, String.Format("Error calling {0}: {1}", methodName, response.ErrorMessage), response.ErrorMessage);
91+
return null;
92+
};
93+
8394
/// <summary>
8495
/// Gets or sets the HTTP timeout (milliseconds) of ApiClient. Default to 100000 milliseconds.
8596
/// </summary>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
using System;
2+
using RestSharp;
3+
4+
namespace {{packageName}}.Client
5+
{
6+
public delegate Exception ExceptionFactory(string methodName, IRestResponse response);
7+
}

modules/swagger-codegen/src/main/resources/csharp/api.mustache

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ namespace {{packageName}}.Api
7575
/// </summary>
7676
public partial class {{classname}} : I{{classname}}
7777
{
78+
private {{packageName}}.Client.ExceptionFactory _exceptionFactory = (name, response) => null;
79+
7880
/// <summary>
7981
/// Initializes a new instance of the <see cref="{{classname}}"/> class.
8082
/// </summary>
@@ -83,6 +85,8 @@ namespace {{packageName}}.Api
8385
{
8486
this.Configuration = new Configuration(new ApiClient(basePath));
8587
88+
ExceptionFactory = {{packageName}}.Client.Configuration.DefaultExceptionFactory;
89+
8690
// ensure API client has configuration ready
8791
if (Configuration.ApiClient.Configuration == null)
8892
{
@@ -103,6 +107,8 @@ namespace {{packageName}}.Api
103107
else
104108
this.Configuration = configuration;
105109
110+
ExceptionFactory = {{packageName}}.Client.Configuration.DefaultExceptionFactory;
111+
106112
// ensure API client has configuration ready
107113
if (Configuration.ApiClient.Configuration == null)
108114
{
@@ -135,6 +141,22 @@ namespace {{packageName}}.Api
135141
/// <value>An instance of the Configuration</value>
136142
public Configuration Configuration {get; set;}
137143

144+
/// <summary>
145+
/// Provides a factory method hook for the creation of exceptions.
146+
/// </summary>
147+
public {{packageName}}.Client.ExceptionFactory ExceptionFactory
148+
{
149+
get
150+
{
151+
if (_exceptionFactory != null && _exceptionFactory.GetInvocationList().Length > 1)
152+
{
153+
throw new InvalidOperationException("Multicast delegate for ExceptionFactory is unsupported.");
154+
}
155+
return _exceptionFactory;
156+
}
157+
set { _exceptionFactory = value; }
158+
}
159+
138160
/// <summary>
139161
/// Gets the default header.
140162
/// </summary>
@@ -276,10 +298,11 @@ namespace {{packageName}}.Api
276298

277299
int localVarStatusCode = (int) localVarResponse.StatusCode;
278300

279-
if (localVarStatusCode >= 400)
280-
throw new ApiException (localVarStatusCode, "Error calling {{operationId}}: " + localVarResponse.Content, localVarResponse.Content);
281-
else if (localVarStatusCode == 0)
282-
throw new ApiException (localVarStatusCode, "Error calling {{operationId}}: " + localVarResponse.ErrorMessage, localVarResponse.ErrorMessage);
301+
if (ExceptionFactory != null)
302+
{
303+
Exception exception = ExceptionFactory("{{operationId}}", localVarResponse);
304+
if (exception != null) throw exception;
305+
}
283306

284307
{{#returnType}}return new ApiResponse<{{{returnType}}}>(localVarStatusCode,
285308
localVarResponse.Headers.ToDictionary(x => x.Name, x => x.Value.ToString()),
@@ -410,10 +433,11 @@ namespace {{packageName}}.Api
410433

411434
int localVarStatusCode = (int) localVarResponse.StatusCode;
412435

413-
if (localVarStatusCode >= 400)
414-
throw new ApiException (localVarStatusCode, "Error calling {{operationId}}: " + localVarResponse.Content, localVarResponse.Content);
415-
else if (localVarStatusCode == 0)
416-
throw new ApiException (localVarStatusCode, "Error calling {{operationId}}: " + localVarResponse.ErrorMessage, localVarResponse.ErrorMessage);
436+
if (ExceptionFactory != null)
437+
{
438+
Exception exception = ExceptionFactory("{{operationId}}", localVarResponse);
439+
if (exception != null) throw exception;
440+
}
417441

418442
{{#returnType}}return new ApiResponse<{{{returnType}}}>(localVarStatusCode,
419443
localVarResponse.Headers.ToDictionary(x => x.Name, x => x.Value.ToString()),

0 commit comments

Comments
 (0)