Skip to content

Commit f15ce3c

Browse files
authored
[fix] Fire response hook before parsing API error to avoid early exit (#323)
- Fire response hook before parsing API error to avoid early exit
1 parent 40d1591 commit f15ce3c

File tree

5 files changed

+144
-8
lines changed

5 files changed

+144
-8
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# CHANGELOG
22

3+
## Next Release
4+
5+
- Fix bug where response hooks were not being called if an API request failed
6+
37
## v7.4.0 (2024-07-24)
48

59
- Add new `Claim` service for filing claims on EasyPost shipments and insurances

src/main/java/com/easypost/http/Requestor.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -606,15 +606,15 @@ private static <T> T httpRequest(final RequestMethod method, final String url, f
606606
}
607607
int rCode = response.getResponseCode();
608608
String rBody = response.getResponseBody();
609-
if (rCode < HttpURLConnection.HTTP_OK || rCode >= HttpURLConnection.HTTP_MULT_CHOICE) {
610-
handleAPIError(rBody, rCode);
611-
}
612609

613610
ResponseHookResponses responseHookResponses = new ResponseHookResponses(rCode, headers, method.toString(), url,
614611
rBody, Instant.now().toString(), requestTimestamp.toString(), requestUuid.toString());
615-
616612
client.getResponseHooks().executeEventHandler(responseHookResponses);
617613

614+
if (rCode < HttpURLConnection.HTTP_OK || rCode >= HttpURLConnection.HTTP_MULT_CHOICE) {
615+
handleAPIError(rBody, rCode);
616+
}
617+
618618
return Constants.Http.GSON.fromJson(rBody, clazz);
619619
}
620620

src/test/cassettes/hook/http_error.json

Lines changed: 88 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/test/java/com/easypost/CarrierAccountTest.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -124,10 +124,6 @@ public void testCreateWithCustomWorkflow() throws EasyPostException {
124124
public void testCreateWithUPS() throws EasyPostException {
125125
vcr.setUpTest("create_with_ups");
126126

127-
Map<String, Object> data = new HashMap<>();
128-
data.put("type", "UpsAccount");
129-
data.put("account_number", "123456789");
130-
131127
CarrierAccount upsAccount = createUpsCarrierAccount();
132128

133129
assertInstanceOf(CarrierAccount.class, upsAccount);

src/test/java/com/easypost/HookTest.java

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.easypost;
22

3+
import com.easypost.exception.API.NotFoundError;
34
import com.easypost.exception.EasyPostException;
45
import com.easypost.hooks.RequestHookResponses;
56
import com.easypost.hooks.ResponseHookResponses;
@@ -9,13 +10,16 @@
910

1011
import static org.junit.jupiter.api.Assertions.assertEquals;
1112
import static org.junit.jupiter.api.Assertions.assertNotNull;
13+
import static org.junit.jupiter.api.Assertions.assertTrue;
1214
import static org.junit.jupiter.api.Assertions.fail;
1315

1416
import java.util.function.Function;
1517

1618
public class HookTest {
1719
private static TestUtils.VCR vcr;
1820

21+
private static boolean hookHit = false;
22+
1923
/**
2024
* Set up the testing environment for this file.
2125
*
@@ -67,6 +71,27 @@ public static Object testRequestHooks(RequestHookResponses data) {
6771
return true;
6872
}
6973

74+
/**
75+
* Test subscribing a response hook when an HTTP error occurs.
76+
*
77+
* @param data The ResponseHookResponses object representing the hook data.
78+
* @return The result of the test.
79+
*/
80+
public static Object testResponseHookOnHttpError(ResponseHookResponses data) {
81+
assertEquals("https://api.easypost.com/v2/parcels/par_123", data.getPath());
82+
assertEquals("GET", data.getMethod());
83+
assertEquals(404, data.getHttpStatus());
84+
assertNotNull(data.getHeaders());
85+
assertNotNull(data.getResponseBody());
86+
assertNotNull(data.getRequestTimestamp());
87+
assertNotNull(data.getRequestTimestamp());
88+
assertNotNull(data.getRequestUuid());
89+
90+
hookHit = true;
91+
92+
return true;
93+
}
94+
7095
/**
7196
* Test subscribing a response hook.
7297
*
@@ -132,6 +157,29 @@ public void testUnsubscribeHooks() throws EasyPostException {
132157
vcr.client.unsubscribeFromResponseHook(failedResponseHook);
133158

134159
vcr.client.parcel.create(Fixtures.basicParcel());
160+
}
161+
162+
/**
163+
* Test that response hooks are still fired even if the HTTP call fails.
164+
*
165+
* @throws EasyPostException when the request fails.
166+
*/
167+
@Test
168+
public void testResponseHookFiredOnHTTPError() throws EasyPostException {
169+
vcr.setUpTest("http_error");
170+
171+
hookHit = false;
172+
173+
Function<ResponseHookResponses, Object> requestHook = HookTest::testResponseHookOnHttpError;
174+
175+
vcr.client.subscribeToResponseHook(requestHook);
176+
177+
try {
178+
vcr.client.parcel.retrieve("par_123");
179+
} catch (NotFoundError e) {
180+
assertEquals(404, e.getStatusCode());
181+
}
135182

183+
assertTrue(hookHit);
136184
}
137185
}

0 commit comments

Comments
 (0)