Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix for issue #354 #355

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ TestResults
*.user
*.sln.docstates
*.userprefs
.vs/

# Build results
[Dd]ebug/
Expand Down
8 changes: 8 additions & 0 deletions src/CommonLibrariesForNET/IJsonHttpClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,23 @@ public interface IJsonHttpClient : IDisposable

// GET
Task<T> HttpGetAsync<T>(string urlSuffix);
Task<T> HttpGetAsync<T, TErrorResponse>(string urlSuffix) where TErrorResponse : IErrorResponse;
Task<T> HttpGetAsync<T>(Uri uri);
Task<T> HttpGetAsync<T, TErrorResponse>(Uri uri) where TErrorResponse : IErrorResponse;
Task<IList<T>> HttpGetAsync<T>(string urlSuffix, string nodeName);
Task<IList<T>> HttpGetAsync<T, TErrorResponse>(string urlSuffix, string nodeName) where TErrorResponse : IErrorResponse;
Task<T> HttpGetRestApiAsync<T>(string apiName);
Task<T> HttpGetRestApiAsync<T, TErrorResponse>(string apiName) where TErrorResponse : IErrorResponse;

// POST
Task<T> HttpPostAsync<T>(object inputObject, string urlSuffix);
Task<T> HttpPostAsync<T, TErrorResponse>(object inputObject, string urlSuffix) where TErrorResponse : IErrorResponse;
Task<T> HttpPostAsync<T>(object inputObject, Uri uri);
Task<T> HttpPostAsync<T, TErrorResponse>(object inputObject, Uri uri) where TErrorResponse : IErrorResponse;
Task<T> HttpPostRestApiAsync<T>(string apiName, object inputObject);
Task<T> HttpPostRestApiAsync<T, TErrorResponse>(string apiName, object inputObject) where TErrorResponse : IErrorResponse;
Task<T> HttpBinaryDataPostAsync<T>(string urlSuffix, object inputObject, byte[] fileContents, string headerName, string fileName);
Task<T> HttpBinaryDataPostAsync<T, TErrorResponse>(string urlSuffix, object inputObject, byte[] fileContents, string headerName, string fileName) where TErrorResponse : IErrorResponse;

// PATCH
Task<SuccessResponse> HttpPatchAsync(object inputObject, string urlSuffix);
Expand Down
74 changes: 64 additions & 10 deletions src/CommonLibrariesForNET/JsonHttpClient.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
Expand All @@ -23,10 +24,11 @@ public JsonHttpClient(string instanceUrl, string apiVersion, string accessToken,
HttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
}

private static ForceException ParseForceException(string responseMessage)
private static ForceException ParseForceException<TErrorResponse>(string responseMessage, HttpStatusCode status)
where TErrorResponse : IErrorResponse
{
var errorResponse = JsonConvert.DeserializeObject<ErrorResponses>(responseMessage);
return new ForceException(errorResponse[0].ErrorCode, errorResponse[0].Message);
var errorResponse = JsonConvert.DeserializeObject<TErrorResponse>(responseMessage);
return errorResponse.MapToForceException(status);
}

// GET
Expand All @@ -37,7 +39,20 @@ public async Task<T> HttpGetAsync<T>(string urlSuffix)
return await HttpGetAsync<T>(url);
}

public async Task<T> HttpGetAsync<T, TErrorResponse>(string urlSuffix)
where TErrorResponse : IErrorResponse
{
var url = Common.FormatUrl(urlSuffix, InstanceUrl, ApiVersion);
return await HttpGetAsync<T, TErrorResponse>(url);
}

public async Task<T> HttpGetAsync<T>(Uri uri)
{
return await HttpGetAsync<T, ErrorResponses>(uri);
}

public async Task<T> HttpGetAsync<T, TErrorResponse>(Uri uri)
where TErrorResponse : IErrorResponse
{
try
{
Expand All @@ -61,11 +76,17 @@ public async Task<T> HttpGetAsync<T>(Uri uri)
}
catch (BaseHttpClientException e)
{
throw ParseForceException(e.Message);
throw ParseForceException<TErrorResponse>(e.Message, e.GetStatus());
}
}

public async Task<IList<T>> HttpGetAsync<T>(string urlSuffix, string nodeName)
{
return await HttpGetAsync<T, ErrorResponses>(urlSuffix, nodeName);
}

public async Task<IList<T>> HttpGetAsync<T, TErrorResponse>(string urlSuffix, string nodeName)
where TErrorResponse : IErrorResponse
{
string next = null;
var records = new List<T>();
Expand All @@ -87,7 +108,7 @@ public async Task<IList<T>> HttpGetAsync<T>(string urlSuffix, string nodeName)
}
catch (BaseHttpClientException e)
{
throw ParseForceException(e.Message);
throw ParseForceException<TErrorResponse>(e.Message, e.GetStatus());
}
}
while (!string.IsNullOrEmpty(next));
Expand Down Expand Up @@ -125,6 +146,13 @@ public async Task<T> HttpGetRestApiAsync<T>(string apiName)
return await HttpGetAsync<T>(url);
}

public async Task<T> HttpGetRestApiAsync<T, TErrorResponse>(string apiName)
where TErrorResponse : IErrorResponse
{
var url = Common.FormatRestApiUrl(apiName, InstanceUrl);
return await HttpGetAsync<T, TErrorResponse>(url);
}

// POST

public async Task<T> HttpPostAsync<T>(object inputObject, string urlSuffix)
Expand All @@ -133,7 +161,20 @@ public async Task<T> HttpPostAsync<T>(object inputObject, string urlSuffix)
return await HttpPostAsync<T>(inputObject, url);
}

public async Task<T> HttpPostAsync<T, TErrorResponse>(object inputObject, string urlSuffix)
where TErrorResponse : IErrorResponse
{
var url = Common.FormatUrl(urlSuffix, InstanceUrl, ApiVersion);
return await HttpPostAsync<T, TErrorResponse>(inputObject, url);
}

public async Task<T> HttpPostAsync<T>(object inputObject, Uri uri)
{
return await HttpPostAsync<T, ErrorResponses>(inputObject, uri);
}

public async Task<T> HttpPostAsync<T, TErrorResponse>(object inputObject, Uri uri)
where TErrorResponse : IErrorResponse
{
var json = JsonConvert.SerializeObject(inputObject,
Formatting.None,
Expand All @@ -150,7 +191,7 @@ public async Task<T> HttpPostAsync<T>(object inputObject, Uri uri)
}
catch (BaseHttpClientException e)
{
throw ParseForceException(e.Message);
throw ParseForceException<TErrorResponse>(e.Message, e.GetStatus());
}
}

Expand All @@ -160,7 +201,20 @@ public async Task<T> HttpPostRestApiAsync<T>(string apiName, object inputObject)
return await HttpPostAsync<T>(inputObject, url);
}

public async Task<T> HttpPostRestApiAsync<T, TErrorResponse>(string apiName, object inputObject)
where TErrorResponse : IErrorResponse
{
var url = Common.FormatRestApiUrl(apiName, InstanceUrl);
return await HttpPostAsync<T, TErrorResponse>(inputObject, url);
}

public async Task<T> HttpBinaryDataPostAsync<T>(string urlSuffix, object inputObject, byte[] fileContents, string headerName, string fileName)
{
return await HttpBinaryDataPostAsync<T, ErrorResponses>(urlSuffix, inputObject, fileContents, headerName, fileName);
}

public async Task<T> HttpBinaryDataPostAsync<T, TErrorResponse>(string urlSuffix, object inputObject, byte[] fileContents, string headerName, string fileName)
where TErrorResponse : IErrorResponse
{
// BRAD: I think we should probably, in time, refactor multipart and binary support to the BaseHttpClient.
// For now though, I just left this in here.
Expand Down Expand Up @@ -193,7 +247,7 @@ public async Task<T> HttpBinaryDataPostAsync<T>(string urlSuffix, object inputOb
return JsonConvert.DeserializeObject<T>(response);
}

throw ParseForceException(response);
throw ParseForceException<TErrorResponse>(response, responseMessage.StatusCode);
}

// PATCH
Expand Down Expand Up @@ -238,7 +292,7 @@ public async Task<SuccessResponse> HttpPatchAsync(object inputObject, Uri uri)
}
catch (BaseHttpClientException e)
{
throw ParseForceException(e.Message);
throw ParseForceException<ErrorResponses>(e.Message, e.GetStatus());
}
}

Expand All @@ -264,7 +318,7 @@ public async Task<SuccessResponse> HttpPatchAsync(object inputObject, Uri uri, N
}
catch (BaseHttpClientException e)
{
throw ParseForceException(e.Message);
throw ParseForceException<ErrorResponses>(e.Message, e.GetStatus());
}
}

Expand All @@ -285,7 +339,7 @@ public async Task<bool> HttpDeleteAsync(string urlSuffix)
}
catch (BaseHttpClientException e)
{
throw ParseForceException(e.Message);
throw ParseForceException<ErrorResponses>(e.Message, e.GetStatus());
}
}
}
Expand Down
10 changes: 9 additions & 1 deletion src/CommonLibrariesForNET/Models/Json/ErrorResponses.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
using System.Collections.Generic;
using System.Linq;
using System.Net;

namespace Salesforce.Common.Models.Json
{
public class ErrorResponses : List<ErrorResponse> { }
public class ErrorResponses : List<ErrorResponse>, IErrorResponse
{
public ForceException MapToForceException(HttpStatusCode status)
{
return new ForceException(this.FirstOrDefault()?.ErrorCode, this.FirstOrDefault()?.Message);
}
}
}
9 changes: 9 additions & 0 deletions src/CommonLibrariesForNET/Models/Json/IErrorResponse.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using System.Net;

namespace Salesforce.Common.Models.Json
{
public interface IErrorResponse
{
ForceException MapToForceException(HttpStatusCode status);
}
}
19 changes: 19 additions & 0 deletions src/ForceToolkitForNET/ForceClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,15 @@ public async Task<T> ExecuteRestApiAsync<T>(string apiName)
var response = await _jsonHttpClient.HttpGetRestApiAsync<T>(apiName);
return response;
}

public async Task<T> ExecuteRestApiAsync<T, TErrorResponse>(string apiName)
where TErrorResponse : IErrorResponse
{
if (string.IsNullOrEmpty(apiName)) throw new ArgumentNullException("apiName");

var response = await _jsonHttpClient.HttpGetRestApiAsync<T, TErrorResponse>(apiName);
return response;
}

public async Task<T> ExecuteRestApiAsync<T>(string apiName, object inputObject)
{
Expand All @@ -90,6 +99,16 @@ public async Task<T> ExecuteRestApiAsync<T>(string apiName, object inputObject)
return response;
}

public async Task<T> ExecuteRestApiAsync<T, TErrorResponse>(string apiName, object inputObject)
where TErrorResponse : IErrorResponse
{
if (string.IsNullOrEmpty(apiName)) throw new ArgumentNullException("apiName");
if (inputObject == null) throw new ArgumentNullException("inputObject");

var response = await _jsonHttpClient.HttpPostRestApiAsync<T, TErrorResponse>(apiName, inputObject);
return response;
}

public async Task<T> QueryByIdAsync<T>(string objectName, string recordId)
{
if (string.IsNullOrEmpty(objectName)) throw new ArgumentNullException("objectName");
Expand Down
2 changes: 2 additions & 0 deletions src/ForceToolkitForNET/IForceClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ public interface IForceClient : IDisposable
Task<T> QueryAllFieldsByIdAsync<T>(string objectName, string recordId);
Task<T> QueryAllFieldsByExternalIdAsync<T>(string objectName, string externalIdFieldName, string externalId);
Task<T> ExecuteRestApiAsync<T>(string apiName);
Task<T> ExecuteRestApiAsync<T, TErrorResponse>(string apiName) where TErrorResponse : IErrorResponse;
Task<T> ExecuteRestApiAsync<T>(string apiName, object inputObject);
Task<T> ExecuteRestApiAsync<T, TErrorResponse>(string apiName, object inputObject) where TErrorResponse : IErrorResponse;
Task<SuccessResponse> CreateAsync(string objectName, object record);
Task<SaveResponse> CreateAsync(string objectName, CreateRequest request);
Task<SuccessResponse> UpdateAsync(string objectName, string recordId, object record);
Expand Down