Skip to content

Commit

Permalink
Improve error message for client configuration failures
Browse files Browse the repository at this point in the history
  • Loading branch information
RDPerera committed Nov 20, 2024
1 parent 6983168 commit f8a026b
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 54 deletions.
30 changes: 15 additions & 15 deletions ballerina/client.bal
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,14 @@ public isolated client class Client {
# + salesforceConfig - Salesforce Connector configuration
# + return - `sfdc:Error` on failure of initialization or else `()`
public isolated function init(ConnectionConfig config) returns error? {
http:Client|http:ClientError|error httpClientResult;
http:Client|http:ClientError httpClientResult;
http:ClientConfiguration httpClientConfig = check config:constructHTTPClientConfig(config);
httpClientResult = trap new (config.baseUrl, httpClientConfig);
httpClientResult = new (config.baseUrl, httpClientConfig);

if httpClientResult is http:Client {
self.salesforceClient = httpClientResult;
} else {
return error(INVALID_CLIENT_CONFIG);
return error(CLIENT_INIT_ERROR_MSG + httpClientResult.message(), httpClientResult);
}
}

Expand Down Expand Up @@ -327,9 +327,9 @@ public isolated client class Client {
returns DeletedRecordsResult|error {
string path = utils:prepareUrl([API_BASE_PATH, SOBJECTS, sObjectName, DELETED]);
string finalUrl = utils:addQueryParameters(path, {
'start: check time:civilToString(removeDecimalPlaces(startDate)),
end: check time:civilToString(removeDecimalPlaces(endDate))
});
'start: check time:civilToString(removeDecimalPlaces(startDate)),
end: check time:civilToString(removeDecimalPlaces(endDate))
});
return check self.salesforceClient->get(finalUrl);
}

Expand All @@ -343,9 +343,9 @@ public isolated client class Client {
returns UpdatedRecordsResults|error {
string path = utils:prepareUrl([API_BASE_PATH, SOBJECTS, sObjectName, UPDATED]);
string finalUrl = utils:addQueryParameters(path, {
'start: check time:civilToString(removeDecimalPlaces(startDate)),
end: check time:civilToString(removeDecimalPlaces(endDate))
});
'start: check time:civilToString(removeDecimalPlaces(startDate)),
end: check time:civilToString(removeDecimalPlaces(endDate))
});
return check self.salesforceClient->get(finalUrl);
}

Expand Down Expand Up @@ -653,12 +653,12 @@ public isolated client class Client {
}

# Get bulk query job results
#
#
# + bulkJobId - Id of the bulk job
# + maxRecords - The maximum number of records to retrieve per set of results for the query
# + return - The resulting string[][] if successful else `error`
isolated remote function getQueryResult(string bulkJobId, int? maxRecords = ()) returns string[][]|error {

string path = "";
string batchingParams = "";

Expand All @@ -668,7 +668,7 @@ public isolated client class Client {
string locator = self.sfLocators.get(bulkJobId);
if locator is "null" {
return [];
}
}
batchingParams = string `results?maxRecords=${maxRecords}&locator=${locator}`;
} else {
batchingParams = string `results?maxRecords=${maxRecords}`;
Expand All @@ -682,15 +682,15 @@ public isolated client class Client {
string locator = self.sfLocators.get(bulkJobId);
if locator is "null" {
return [];
}
}
batchingParams = string `results?locator=${locator}`;
path = utils:prepareUrl([API_BASE_PATH, JOBS, QUERY, bulkJobId, batchingParams]);
} else {
path = utils:prepareUrl([API_BASE_PATH, JOBS, QUERY, bulkJobId, RESULT]);
}
}
}
}

http:Response response = check self.salesforceClient->get(path);
if response.statusCode == 200 {
string textPayload = check response.getTextPayload();
Expand Down
5 changes: 2 additions & 3 deletions ballerina/errors.bal
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public type Error error<ErrorDetails>;
#
# + errorCode - Error code from Salesforce
# + message - Response body with extra information
#
#
public type ErrorDetails record {
string? errorCode?;
string? message?;
Expand All @@ -37,6 +37,5 @@ const STATUS_CODE = "statusCode";
const HEADERS = "headers";
const BODY = "body";


public const string CLIENT_INIT_ERROR_MSG = "Error occurred while initializing the client: ";
public const string ERR_EXTRACTING_ERROR_MSG = "Error occured while extracting errors from payload.";
public const string INVALID_CLIENT_CONFIG = "Invalid values provided for client configuration parameters.";
34 changes: 15 additions & 19 deletions ballerina/modules/bulk/client.bal
Original file line number Diff line number Diff line change
Expand Up @@ -39,30 +39,26 @@ public isolated client class Client {
# + return - An error on failure of initialization or else `()`
public isolated function init(ConnectionConfig config) returns error? {
http:ClientConfiguration httpClientConfig = check config:constructHTTPClientConfig(config);
http:OAuth2RefreshTokenGrantConfig|http:BearerTokenConfig auth = let var authConfig = config.auth in
(authConfig is http:BearerTokenConfig ? authConfig : {...authConfig});
http:OAuth2RefreshTokenGrantConfig|http:BearerTokenConfig auth = let var authConfig = config.auth in
(authConfig is http:BearerTokenConfig ? authConfig : {...authConfig});
self.clientConfig = auth.cloneReadOnly();

http:ClientOAuth2Handler|http:ClientBearerTokenAuthHandler|error httpHandlerResult;
if auth is http:OAuth2RefreshTokenGrantConfig {
httpHandlerResult = trap new http:ClientOAuth2Handler(auth);
} else {
httpHandlerResult = trap new http:ClientBearerTokenAuthHandler(auth);
}
http:ClientOAuth2Handler|http:ClientBearerTokenAuthHandler httpHandlerResult;

if httpHandlerResult is http:ClientOAuth2Handler|http:ClientBearerTokenAuthHandler {
self.clientHandler = httpHandlerResult;
if auth is http:OAuth2RefreshTokenGrantConfig {
httpHandlerResult = new http:ClientOAuth2Handler(auth);
} else {
return error(INVALID_CLIENT_CONFIG);
httpHandlerResult = new http:ClientBearerTokenAuthHandler(auth);
}
self.clientHandler = httpHandlerResult;

http:Client|http:ClientError|error httpClientResult;
httpClientResult = trap new (config.baseUrl, httpClientConfig);
http:Client|http:ClientError httpClientResult;
httpClientResult = new (config.baseUrl, httpClientConfig);

if httpClientResult is http:Client {
self.salesforceClient = httpClientResult;
} else {
return error(INVALID_CLIENT_CONFIG);
return error(utils:CLIENT_INIT_ERROR_MSG + httpClientResult.message(), httpClientResult);
}
}

Expand Down Expand Up @@ -106,7 +102,7 @@ public isolated client class Client {
#
# + bulkJob - `BulkJob` record of which the info is required
# + return - `JobInfo` record or `error`
isolated remote function getJobInfo(BulkJob bulkJob)returns error|JobInfo {
isolated remote function getJobInfo(BulkJob bulkJob) returns error|JobInfo {
string jobId = bulkJob.jobId;
JobType jobDataType = bulkJob.jobDataType;
string path = utils:prepareUrl([SERVICES, ASYNC, BULK_API_VERSION, JOB, jobId]);
Expand Down Expand Up @@ -157,7 +153,7 @@ public isolated client class Client {
# + content - Batch content
# + return - Batch info or `error`
isolated remote function addBatch(BulkJob bulkJob,
json|string|xml|string[][]|stream<string[], error?>|io:ReadableByteChannel content)
json|string|xml|string[][]|stream<string[], error?>|io:ReadableByteChannel content)
returns error|BatchInfo {
string path = utils:prepareUrl([SERVICES, ASYNC, BULK_API_VERSION, JOB, bulkJob.jobId, BATCH]);
// https://github.com/ballerina-platform/ballerina-lang/issues/26798
Expand Down Expand Up @@ -305,23 +301,23 @@ public isolated client class Client {
json resultResponse = check checkJsonPayloadAndSetErrors(response);
if QUERY == bulkJob.operation {
return getJsonQueryResult(resultResponse, path, self.salesforceClient,
self.clientHandler);
self.clientHandler);
}
return createBatchResultRecordFromJson(resultResponse);
}
XML => {
xml resultResponse = check checkXmlPayloadAndSetErrors(response);
if QUERY == bulkJob.operation {
return getXmlQueryResult(resultResponse, path, self.salesforceClient,
self.clientHandler);
self.clientHandler);
}
return createBatchResultRecordFromXml(resultResponse);
}
CSV => {
if QUERY == bulkJob.operation {
xml resultResponse = check checkXmlPayloadAndSetErrors(response);
return getCsvQueryResult(resultResponse, path, self.salesforceClient,
self.clientHandler);
self.clientHandler);
}
string resultResponse = check checkTextPayloadAndSetErrors(response);
return createBatchResultRecordFromCsv(resultResponse);
Expand Down
3 changes: 1 addition & 2 deletions ballerina/modules/bulk/constants.bal
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,4 @@ const string FORWARD_SLASH = "/";
# Constant field `JSON_STATE_CLOSED_PAYLOAD`. Holds the value of JSON body which needs to close the job.
final json JSON_STATE_CLOSED_PAYLOAD = {state: "Closed"};

public const string ERR_EXTRACTING_ERROR_MSG = "Error occured while extracting errors from payload.";
public const INVALID_CLIENT_CONFIG = "Invalid values provided for client configuration parameters.";
public const string ERR_EXTRACTING_ERROR_MSG = "Error occurred while extracting errors from payload.";
21 changes: 8 additions & 13 deletions ballerina/modules/soap/client.bal
Original file line number Diff line number Diff line change
Expand Up @@ -39,29 +39,24 @@ public isolated client class Client {
# + return - An error on failure of initialization or else `()`
public isolated function init(ConnectionConfig config) returns error? {
http:ClientConfiguration httpClientConfig = check config:constructHTTPClientConfig(config);
http:OAuth2RefreshTokenGrantConfig|http:BearerTokenConfig auth = let var authConfig = config.auth in
(authConfig is http:BearerTokenConfig ? authConfig : {...authConfig});
http:OAuth2RefreshTokenGrantConfig|http:BearerTokenConfig auth = let var authConfig = config.auth in
(authConfig is http:BearerTokenConfig ? authConfig : {...authConfig});
self.clientConfig = auth.cloneReadOnly();

http:ClientOAuth2Handler|http:ClientBearerTokenAuthHandler|error httpHandlerResult;
http:ClientOAuth2Handler|http:ClientBearerTokenAuthHandler httpHandlerResult;
if auth is http:OAuth2RefreshTokenGrantConfig {
httpHandlerResult = trap new http:ClientOAuth2Handler(auth);
httpHandlerResult = new http:ClientOAuth2Handler(auth);
} else {
httpHandlerResult = trap new http:ClientBearerTokenAuthHandler(auth);
httpHandlerResult = new http:ClientBearerTokenAuthHandler(auth);
}
self.clientHandler = httpHandlerResult;

if httpHandlerResult is http:ClientOAuth2Handler|http:ClientBearerTokenAuthHandler {
self.clientHandler = httpHandlerResult;
} else {
return error(utils:INVALID_CLIENT_CONFIG);
}

http:Client|error httpClientResult = trap new (config.baseUrl, httpClientConfig);
http:Client|http:ClientError httpClientResult = new (config.baseUrl, httpClientConfig);

if httpClientResult is http:Client {
self.salesforceClient = httpClientResult;
} else {
return error(utils:INVALID_CLIENT_CONFIG);
return error(utils:CLIENT_INIT_ERROR_MSG + httpClientResult.message(), httpClientResult);
}
}

Expand Down
3 changes: 1 addition & 2 deletions ballerina/modules/utils/constants.bal
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,5 @@ const string QUESTION_MARK = "?";
# Constant field `EQUAL_SIGN`. Holds the value of "=".
const string EQUAL_SIGN = "=";

public const INVALID_CLIENT_CONFIG = "Invalid values provided for client configuration parameters.";
public const string CLIENT_INIT_ERROR_MSG = "Error occurred while initializing the client: ";
const ERR_EXTRACTING_ERROR_MSG = "Error occured while extracting errors from payload.";

0 comments on commit f8a026b

Please sign in to comment.