Skip to content

Commit 270cfed

Browse files
committed
feat(Error): Add specific 402 errors
- IdpcBalanceDepletedError - catches balance depleted - IdpcLimitReachedError - catches daily ip and daily key limit reached errors
1 parent 9d082a7 commit 270cfed

File tree

5 files changed

+58
-4
lines changed

5 files changed

+58
-4
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,8 @@ IdealPostcodesError < Error
468468
|- IdpcBadRequestError # 400 Errors
469469
|- IdpcUnauthorisedError # 401 Errors
470470
|- IdpcRequestFailedError # 402 Errors
471+
| |- IdpcBalanceDepletedError
472+
| |- IdpcLimitReachedError
471473
|
472474
|- IdpcResourceNotFoundError # 404 Errors
473475
| |- IdpcPostcodeNotFoundError

lib/error.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,23 @@ export class IdpcInvalidKeyError extends IdpcUnauthorisedError {}
123123
*/
124124
export class IdpcRequestFailedError extends IdpcApiError {}
125125

126+
/**
127+
* IdpcBalanceDepleted
128+
*
129+
* Balance on key has been depleted
130+
*/
131+
export class IdpcBalanceDepletedError extends IdpcRequestFailedError {}
132+
133+
/**
134+
* IdpcLimitReachedError
135+
*
136+
* Limit reached. One of your lookup limits has been breached for today. This
137+
* could either be your total daily limit on your key or the individual IP
138+
* limit. You can either wait for for the limit to reset (after a day) or
139+
* manually disable or increase your limit.
140+
*/
141+
export class IdpcLimitReachedError extends IdpcRequestFailedError {}
142+
126143
/**
127144
* IdpcResourceNotFoundError
128145
*
@@ -185,6 +202,8 @@ const INVALID_KEY = 4010;
185202

186203
// 402 Responses
187204
const PAYMENT_REQUIRED = 402;
205+
const BALANCE_DEPLETED = 4020;
206+
const LIMIT_REACHED = 4021;
188207

189208
// 404 Responses
190209
const NOT_FOUND = 404;
@@ -236,6 +255,9 @@ export const parse = (response: HttpResponse): Error | void => {
236255
if (code === KEY_NOT_FOUND) return new IdpcKeyNotFoundError(response);
237256
if (code === UDPRN_NOT_FOUND) return new IdpcUdprnNotFoundError(response);
238257
if (code === UMPRN_NOT_FOUND) return new IdpcUmprnNotFoundError(response);
258+
if (code === BALANCE_DEPLETED)
259+
return new IdpcBalanceDepletedError(response);
260+
if (code === LIMIT_REACHED) return new IdpcLimitReachedError(response);
239261

240262
// If no API errors of interest detected, fall back to http status code
241263
if (httpStatus === NOT_FOUND)

test/addresses.resource.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as sinon from "sinon";
2-
import { IdpcRequestFailedError } from "../lib/error";
2+
import { IdpcRequestFailedError, IdpcBalanceDepletedError } from "../lib/error";
33
import { addresses, errors } from "@ideal-postcodes/api-fixtures";
44
import { create, AddressResource } from "../lib/resources/addresses";
55
import { HttpVerb } from "../lib/agent";
@@ -76,7 +76,8 @@ describe("AddressesResource", () => {
7676
.list({ query })
7777
.then(() => done(new Error("Promise should be rejected")))
7878
.catch(error => {
79-
assert.instanceOf(error, IdpcRequestFailedError);
79+
assert.isTrue(error instanceof IdpcRequestFailedError);
80+
assert.instanceOf(error, IdpcBalanceDepletedError);
8081
done();
8182
});
8283
});

test/autocomplete.resource.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as sinon from "sinon";
2-
import { IdpcRequestFailedError } from "../lib/error";
2+
import { IdpcRequestFailedError, IdpcBalanceDepletedError } from "../lib/error";
33
import { errors, autocomplete } from "@ideal-postcodes/api-fixtures";
44
import { create, AutocompleteResource } from "../lib/resources/autocomplete";
55
import { HttpVerb } from "../lib/agent";
@@ -76,7 +76,8 @@ describe("AutocompleteResource", () => {
7676
.list({ query })
7777
.then(() => done(new Error("Promise should be rejected")))
7878
.catch(error => {
79-
assert.instanceOf(error, IdpcRequestFailedError);
79+
assert.instanceOf(error, IdpcBalanceDepletedError);
80+
assert.isTrue(error instanceof IdpcRequestFailedError);
8081
done();
8182
});
8283
});

test/error.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ describe("Error", () => {
7676
assert.deepEqual(error.response, httpResponse);
7777
assert.equal(error.message, httpResponse.body.message);
7878
assert.equal(error.httpStatus, httpResponse.httpStatus);
79+
assert.deepEqual(error.metadata, {});
7980
assert.equal(error.name, "Ideal Postcodes Error");
8081
});
8182

@@ -192,6 +193,33 @@ describe("Error", () => {
192193
});
193194
});
194195

196+
describe("IdpcBalanceDepletedError", () => {
197+
describe("instantiation", () => {
198+
idpcApiErrorSuite({
199+
httpResponse: toResponse(errors.balanceDepleted),
200+
ErrorKlass: IdpcRequestFailedError,
201+
});
202+
});
203+
});
204+
205+
describe("IdpcLimitReachedError", () => {
206+
describe("instantiation", () => {
207+
idpcApiErrorSuite({
208+
httpResponse: toResponse(errors.dailyIpRateLimitReached),
209+
ErrorKlass: IdpcRequestFailedError,
210+
});
211+
});
212+
});
213+
214+
describe("IdpcLimitReachedError", () => {
215+
describe("instantiation", () => {
216+
idpcApiErrorSuite({
217+
httpResponse: toResponse(errors.dailyLimitReached),
218+
ErrorKlass: IdpcRequestFailedError,
219+
});
220+
});
221+
});
222+
195223
describe("IdpcServerError", () => {
196224
describe("instantiation", () => {
197225
const httpResponse = {

0 commit comments

Comments
 (0)