Skip to content

Commit

Permalink
Sp/better handling of errors (#60)
Browse files Browse the repository at this point in the history
* POC for how to handle error responses better

* refactor

* fix test case, start putting together new test cases

* cleanup

* wrap up refactoring

* Update documentation

* update docs
  • Loading branch information
Crim authored Sep 21, 2020
1 parent 3949bb0 commit 3c0bdb3
Show file tree
Hide file tree
Showing 12 changed files with 842 additions and 186 deletions.
97 changes: 95 additions & 2 deletions 3_0_0_migration_notes.MD
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Pardot Java API Client 2.x.x to 3.0.0 Migration Guide

## Authentication & Configuration Breaking Changes
## Breaking Change : Authentication & Configuration

In order to properly support the transition of the Pardot API from authenticating using Pardot username, password, and user keys, to
Salesforce Single Signon, several breaking changes were made to how you configure the Pardot API Client.
Expand Down Expand Up @@ -48,4 +48,97 @@ final ConfigurationBuilder configuration = Configuration.newBuilder()
final PardotClient client = new PardotClient(configuration);
```

See [Offical Pardot Developer Documentation](https://developer.pardot.com/kb/authentication/) and [Salesforce OAuth Setup](https://help.salesforce.com/articleView?id=remoteaccess_oauth_flows.htm) for details on how to obtain the above required properties.
See [Offical Pardot Developer Documentation](https://developer.pardot.com/kb/authentication/) and [Salesforce OAuth Setup](https://help.salesforce.com/articleView?id=remoteaccess_oauth_flows.htm) for details on how to obtain the above required properties.

## Breaking Change : Read request methods now return Optionals

Previously methods on `PardotClient` for reading objects (such as `PardotClient.readProspect()`, `PardotClient.readCampaign()`, etc...)
either returned the object you wished to retrieve, or threw an `InvalidRequestException` if the API returned a response stating that the record
could not be found.

This often led to code like:
```java
// Try to lookup prospect by Email.
Prospect myProspect = null;
try {
myProspect = client.prospectRead(new ProspectReadRequest()
.selectByEmail("[email protected]")
);
} catch (final InvalidRequestException exception) {
// Prospect could not be found. Swallow exception.
}

// Handle prospect if found
if (myProspect != null) {
...
}
```

These methods now return `Optional<T>`,which means you no longer need to catch and handle `InvalidRequestException`
when an object is unable to be found in the API. The above example code can be simplified to:

```java
// Check if the Optional is present
final Optional<Prospect> prospectResponse = client.prospectRead(new ProspectReadRequest()
.selectByEmail("[email protected]")
);
if (prospectResponse.isPresent()) {
final Prospect myProspect = prospectResponse.get()
}

// Or even better by using the methods available on Optional
client.prospectRead(new ProspectReadRequest()
.selectByEmail('[email protected]')
).ifPresent((prospect) -> {
// Make use of prospect if found
logger.info("Found prospect: {}", prospect.getEmail());
});
```

## Breaking Change : Delete request methods no longer return boolean

Previously methods on `PardotClient` for deleting objects (such as `PardotClient.deleteProspect()`, `PardotClient.deleteCampaign()`, etc...)
always returned a value of `true` regardless if the delete request was successful or not. Version 3.0.0 changes the return type for these methods
to a type of `Result<Boolean>`. The [Result](src/main/java/com/darksci/pardot/api/response/Result.java) object
allows for returning a successful response (value of boolean `true`) as well as an [ErrorResponse](src/main/java/com/darksci/pardot/api/response/ErrorResponse.java)
instance if the request was not successful.

The quick way to simply migrate your code:

```java
// Code that looked like the following:
final boolean result = client.userDelete(deleteRequest);
// or
if (client.userDelete(deleteRequest)) {

// Now should look like:
final boolean result = client.userDelete(deleteRequest).isSuccess();
// or
if (client.userDelete(deleteRequest.isSuccess())) {
```

But this new return type also gives you additional flexibility to handle errors more gracefully:
```java
// Handle success conditions:
client
.userDelete(deleteRequest)
.ifSuccess((success) -> logger.info("Successfully deleted user!"));

// Handle error conditions:
client
.userDelete(deleteRequest)
.ifError((error -> logger.info("Failed to delete user: {}", error.getMessage())));

// Or handle both cases:
client
.userDelete(deleteRequest)
.handle(
(success) -> {
logger.info("Successfully deleted user!");
return true;
},
(error) -> {
logger.info("Error deleting user: {}", error.getMessage());
return false;
});
```
7 changes: 5 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).

## 3.0.0 (UNRELEASED)

### Breaking Changes
This release has several breaking changes. See [3.0.0 Migration Notes](3_0_0_migration_notes.MD) for details on breaking changes and how to upgrade.

- [ISSUE-58](https://github.com/Crim/pardot-java-client/issues/58) Add support for Salesforce SSO authentication.
- [PR-60](https://github.com/Crim/pardot-java-client/pull/60) Alters return values from `PardotClient.readXYZ()` and `PardotClient.deleteXYZ()` to allow for better error handling.

### Breaking Change
See [3.0.0 Migration Notes](3_0_0_migration_notes.MD) for details on breaking changes and how to upgrade.

## 2.1.0 (07/30/2020)
- [ISSUE-56](https://github.com/Crim/pardot-java-client/issues/56) Adds support for Dynamic Content.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@
public class InvalidRequestException extends RuntimeException {
private final int errorCode;

/**
* Constructor.
* @param message Error message returned by Pardot API.
* @param errorCode Error code returned by Pardot API.
*/
public InvalidRequestException(final String message, final int errorCode) {
super(message);
this.errorCode = errorCode;
Expand Down
Loading

0 comments on commit 3c0bdb3

Please sign in to comment.