Skip to content

Commit

Permalink
feat: adding retryable on error handler
Browse files Browse the repository at this point in the history
  • Loading branch information
barbmarcio committed Jul 26, 2024
1 parent c97d97f commit 0f498b0
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 11 deletions.
2 changes: 2 additions & 0 deletions src/constants/apis.constant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ export const apis = {
auctions: "v2/auctions",
events: "v2/events",
};

export const retryableStatusCodes = [429, 500, 502, 503, 504];
20 changes: 12 additions & 8 deletions src/functions/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { apis, baseURL } from "../constants/apis.constant";
import APIClient from "../lib/api-client";
import AppError from "../lib/app-error";
import { withValidation } from "../lib/with-validation";
import type { TopsortEvent } from "../types/events";
import type { EventResult, TopsortEvent } from "../types/events";
import type { Config } from "../types/shared";

/**
Expand All @@ -18,9 +18,9 @@ import type { Config } from "../types/shared";
*
* @param config - The configuration object containing the API Key and optionally, the Host.
* @param event - The event to report.
* @returns {Promise<{ok: boolean}>} The result of the report, indicating success.
* @returns {Promise<EventResult>} The result of the report, indicating success.
*/
async function handler(config: Config, event: TopsortEvent): Promise<{ ok: boolean }> {
async function handler(config: Config, event: TopsortEvent): Promise<EventResult> {
let url: URL;
try {
url = new URL(`${config.host || baseURL}/${apis.events}`);
Expand All @@ -30,11 +30,15 @@ async function handler(config: Config, event: TopsortEvent): Promise<{ ok: boole
});
}

await APIClient.post(url.toString(), event, config);

return {
ok: true,
};
try {
await APIClient.post(url.toString(), event, config);
return { ok: true, retry: false };
} catch (error) {
if (error instanceof AppError && error.retry) {
return { ok: false, retry: true };
}
throw error;
}
}

export const reportEvent = withValidation(handler);
5 changes: 3 additions & 2 deletions src/lib/api-client.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { version } from "../../package.json";
import { baseURL } from "../constants/apis.constant";
import { baseURL, retryableStatusCodes } from "../constants/apis.constant";
import type { Config } from "../types/shared";
import AppError from "./app-error";

Expand All @@ -20,7 +20,8 @@ class APIClient {
}

if (!response.ok) {
throw new AppError(response.status, response.statusText, data);
const retry = retryableStatusCodes.includes(response.status);
throw new AppError(response.status, response.statusText, data, retry);
}

return data;
Expand Down
4 changes: 3 additions & 1 deletion src/lib/app-error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ class AppError {
public readonly status: number; //change later to http status code
public readonly statusText: string;
public readonly body: unknown;
public readonly retry: boolean;

constructor(status: number, statusText: string, body: unknown) {
constructor(status: number, statusText: string, body: unknown, retry = false) {
this.status = status;
this.statusText = statusText;
this.body = body;
this.retry = retry;
}
}

Expand Down
5 changes: 5 additions & 0 deletions src/types/events.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,8 @@ export interface TopsortEvent {
clicks?: Click[];
purchases?: Purchase[];
}

export interface EventResult {
ok: boolean;
retry: boolean;
}

0 comments on commit 0f498b0

Please sign in to comment.