[csharp] Intercept hooks for req/res and ExceptionFactory

This commit is contained in:
Jim Schubert 2016-05-27 22:10:06 -04:00
parent f5ff62e685
commit fafcd33e27
5 changed files with 72 additions and 10 deletions

View File

@ -233,6 +233,8 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
clientPackageDir, "ApiException.cs")); clientPackageDir, "ApiException.cs"));
supportingFiles.add(new SupportingFile("ApiResponse.mustache", supportingFiles.add(new SupportingFile("ApiResponse.mustache",
clientPackageDir, "ApiResponse.cs")); clientPackageDir, "ApiResponse.cs"));
supportingFiles.add(new SupportingFile("ExceptionFactory.mustache",
clientPackageDir, "ExceptionFactory.cs"));
supportingFiles.add(new SupportingFile("compile.mustache", "", "build.bat")); supportingFiles.add(new SupportingFile("compile.mustache", "", "build.bat"));
supportingFiles.add(new SupportingFile("compile-mono.sh.mustache", "", "build.sh")); supportingFiles.add(new SupportingFile("compile-mono.sh.mustache", "", "build.sh"));

View File

@ -17,15 +17,28 @@ using RestSharp;
namespace {{packageName}}.Client namespace {{packageName}}.Client
{ {
/// <summary> /// <summary>
/// API client is mainly responible for making the HTTP call to the API backend. /// API client is mainly responsible for making the HTTP call to the API backend.
/// </summary> /// </summary>
public class ApiClient public partial class ApiClient
{ {
private JsonSerializerSettings serializerSettings = new JsonSerializerSettings private JsonSerializerSettings serializerSettings = new JsonSerializerSettings
{ {
ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor
}; };
/// <summary>
/// Allows for extending request processing for <see cref="ApiClient"/> generated code.
/// </summary>
/// <param name="request">The RestSharp request object</param>
partial void InterceptRequest(IRestRequest request);
/// <summary>
/// Allows for extending response processing for <see cref="ApiClient"/> generated code.
/// </summary>
/// <param name="request">The RestSharp request object</param>
/// <param name="response">The RestSharp response object</param>
partial void InterceptResponse(IRestRequest request, IRestResponse response);
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="ApiClient" /> class /// Initializes a new instance of the <see cref="ApiClient" /> class
/// with default configuration and base path ({{basePath}}). /// with default configuration and base path ({{basePath}}).
@ -165,6 +178,7 @@ namespace {{packageName}}.Client
// set user agent // set user agent
RestClient.UserAgent = Configuration.UserAgent; RestClient.UserAgent = Configuration.UserAgent;
InterceptRequest(request);
{{^supportsUWP}} {{^supportsUWP}}
var response = RestClient.Execute(request); var response = RestClient.Execute(request);
{{/supportsUWP}} {{/supportsUWP}}
@ -172,6 +186,8 @@ namespace {{packageName}}.Client
// Using async method to perform sync call (uwp-only) // Using async method to perform sync call (uwp-only)
var response = RestClient.ExecuteTaskAsync(request).Result; var response = RestClient.ExecuteTaskAsync(request).Result;
{{/supportsUWP}} {{/supportsUWP}}
InterceptResponse(request, response);
return (Object) response; return (Object) response;
} }
{{#supportsAsync}} {{#supportsAsync}}
@ -197,7 +213,9 @@ namespace {{packageName}}.Client
var request = PrepareRequest( var request = PrepareRequest(
path, method, queryParams, postBody, headerParams, formParams, fileParams, path, method, queryParams, postBody, headerParams, formParams, fileParams,
pathParams, contentType); pathParams, contentType);
InterceptRequest(request);
var response = await RestClient.ExecuteTaskAsync(request); var response = await RestClient.ExecuteTaskAsync(request);
InterceptResponse(request, response);
return (Object)response; return (Object)response;
}{{/supportsAsync}} }{{/supportsAsync}}

View File

@ -80,6 +80,17 @@ namespace {{packageName}}.Client
/// <value>Configuration.</value> /// <value>Configuration.</value>
public static Configuration Default = new Configuration(); public static Configuration Default = new Configuration();
/// <summary>
/// Default creation of exceptions for a given method name and response object
/// </summary>
public static readonly ExceptionFactory DefaultExceptionFactory = (methodName, response) =>
{
int status = (int) response.StatusCode;
if (status >= 400) return new ApiException(status, String.Format("Error calling {0}: {1}", methodName, response.Content), response.Content);
if (status == 0) return new ApiException(status, String.Format("Error calling {0}: {1}", methodName, response.ErrorMessage), response.ErrorMessage);
return null;
};
/// <summary> /// <summary>
/// Gets or sets the HTTP timeout (milliseconds) of ApiClient. Default to 100000 milliseconds. /// Gets or sets the HTTP timeout (milliseconds) of ApiClient. Default to 100000 milliseconds.
/// </summary> /// </summary>

View File

@ -0,0 +1,7 @@
using System;
using RestSharp;
namespace {{packageName}}.Client
{
public delegate Exception ExceptionFactory(string methodName, IRestResponse response);
}

View File

@ -75,6 +75,8 @@ namespace {{packageName}}.Api
/// </summary> /// </summary>
public partial class {{classname}} : I{{classname}} public partial class {{classname}} : I{{classname}}
{ {
private {{packageName}}.Client.ExceptionFactory _exceptionFactory = (name, response) => null;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="{{classname}}"/> class. /// Initializes a new instance of the <see cref="{{classname}}"/> class.
/// </summary> /// </summary>
@ -83,6 +85,8 @@ namespace {{packageName}}.Api
{ {
this.Configuration = new Configuration(new ApiClient(basePath)); this.Configuration = new Configuration(new ApiClient(basePath));
ExceptionFactory = {{packageName}}.Client.Configuration.DefaultExceptionFactory;
// ensure API client has configuration ready // ensure API client has configuration ready
if (Configuration.ApiClient.Configuration == null) if (Configuration.ApiClient.Configuration == null)
{ {
@ -103,6 +107,8 @@ namespace {{packageName}}.Api
else else
this.Configuration = configuration; this.Configuration = configuration;
ExceptionFactory = {{packageName}}.Client.Configuration.DefaultExceptionFactory;
// ensure API client has configuration ready // ensure API client has configuration ready
if (Configuration.ApiClient.Configuration == null) if (Configuration.ApiClient.Configuration == null)
{ {
@ -135,6 +141,22 @@ namespace {{packageName}}.Api
/// <value>An instance of the Configuration</value> /// <value>An instance of the Configuration</value>
public Configuration Configuration {get; set;} public Configuration Configuration {get; set;}
/// <summary>
/// Provides a factory method hook for the creation of exceptions.
/// </summary>
public {{packageName}}.Client.ExceptionFactory ExceptionFactory
{
get
{
if (_exceptionFactory != null && _exceptionFactory.GetInvocationList().Length > 1)
{
throw new InvalidOperationException("Multicast delegate for ExceptionFactory is unsupported.");
}
return _exceptionFactory;
}
set { _exceptionFactory = value; }
}
/// <summary> /// <summary>
/// Gets the default header. /// Gets the default header.
/// </summary> /// </summary>
@ -276,10 +298,11 @@ namespace {{packageName}}.Api
int localVarStatusCode = (int) localVarResponse.StatusCode; int localVarStatusCode = (int) localVarResponse.StatusCode;
if (localVarStatusCode >= 400) if (ExceptionFactory != null)
throw new ApiException (localVarStatusCode, "Error calling {{operationId}}: " + localVarResponse.Content, localVarResponse.Content); {
else if (localVarStatusCode == 0) Exception exception = ExceptionFactory("{{operationId}}", localVarResponse);
throw new ApiException (localVarStatusCode, "Error calling {{operationId}}: " + localVarResponse.ErrorMessage, localVarResponse.ErrorMessage); if (exception != null) throw exception;
}
{{#returnType}}return new ApiResponse<{{{returnType}}}>(localVarStatusCode, {{#returnType}}return new ApiResponse<{{{returnType}}}>(localVarStatusCode,
localVarResponse.Headers.ToDictionary(x => x.Name, x => x.Value.ToString()), localVarResponse.Headers.ToDictionary(x => x.Name, x => x.Value.ToString()),
@ -410,10 +433,11 @@ namespace {{packageName}}.Api
int localVarStatusCode = (int) localVarResponse.StatusCode; int localVarStatusCode = (int) localVarResponse.StatusCode;
if (localVarStatusCode >= 400) if (ExceptionFactory != null)
throw new ApiException (localVarStatusCode, "Error calling {{operationId}}: " + localVarResponse.Content, localVarResponse.Content); {
else if (localVarStatusCode == 0) Exception exception = ExceptionFactory("{{operationId}}", localVarResponse);
throw new ApiException (localVarStatusCode, "Error calling {{operationId}}: " + localVarResponse.ErrorMessage, localVarResponse.ErrorMessage); if (exception != null) throw exception;
}
{{#returnType}}return new ApiResponse<{{{returnType}}}>(localVarStatusCode, {{#returnType}}return new ApiResponse<{{{returnType}}}>(localVarStatusCode,
localVarResponse.Headers.ToDictionary(x => x.Name, x => x.Value.ToString()), localVarResponse.Headers.ToDictionary(x => x.Name, x => x.Value.ToString()),