Skip to content

Commit ed6ab67

Browse files
committed
add rate limiting as a property that always appears in all responses, instead of only in errors
1 parent c646c82 commit ed6ab67

File tree

2 files changed

+44
-27
lines changed

2 files changed

+44
-27
lines changed

src/interfaces.ts

Lines changed: 16 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { RateLimit } from './rate-limiting';
2+
13
export const RESEND_ERROR_CODES_BY_KEY = {
24
missing_required_field: 422,
35
invalid_idempotency_key: 400,
@@ -19,35 +21,22 @@ export const RESEND_ERROR_CODES_BY_KEY = {
1921

2022
export type RESEND_ERROR_CODE_KEY = keyof typeof RESEND_ERROR_CODES_BY_KEY;
2123

22-
export type ErrorResponse =
24+
export type ErrorResponse = {
25+
message: string;
26+
name: RESEND_ERROR_CODE_KEY;
27+
};
28+
29+
export type Response<Data> = (
2330
| {
24-
message: string;
25-
name: Exclude<RESEND_ERROR_CODE_KEY, 'rate_limit_exceeded'>;
31+
data: Data;
32+
error: null;
2633
}
2734
| {
28-
name: Extract<RESEND_ERROR_CODE_KEY, 'rate_limit_exceeded'>;
29-
message: string;
30-
/**
31-
* Information to help you with remediation of the error, for example,
32-
* waiting for `retry_after` before retrying a rate limited request.
33-
*/
34-
remediation: {
35-
/**
36-
* Time in seconds after which the request can be retried.
37-
*/
38-
retry_after: number;
39-
40-
/**
41-
* The number of requests allowed per {@member reset}.
42-
*/
43-
limit: number;
44-
/**
45-
* Time in seconds for the limit
46-
*/
47-
reset: number;
48-
49-
policy: string;
50-
};
51-
};
35+
data: null;
36+
error: ErrorResponse;
37+
}
38+
) & {
39+
rateLimiting: RateLimit;
40+
};
5241

5342
export type Tag = { name: string; value: string };

src/rate-limiting.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
export type RateLimit = {
2+
limit: number;
3+
remainingRequests: number;
4+
shouldResetAfter: number;
5+
};
6+
7+
export function parseRateLimit(headers: Headers): RateLimit | undefined {
8+
const limitHeader = headers.get('ratelimit-limit');
9+
const remainingHeader = headers.get('ratelimit-remaining');
10+
const resetHeader = headers.get('ratelimit-reset');
11+
12+
if (!limitHeader || !remainingHeader || !resetHeader) {
13+
console.warn(
14+
"The rate limit headers are not present in the response, something must've gone wrong, please email us at support@resend.com",
15+
);
16+
return undefined;
17+
}
18+
19+
const limit = Number.parseInt(limitHeader, 10);
20+
const remaining = Number.parseInt(remainingHeader, 10);
21+
const reset = Number.parseInt(resetHeader, 10);
22+
23+
return {
24+
limit,
25+
remainingRequests: remaining,
26+
shouldResetAfter: reset,
27+
};
28+
}

0 commit comments

Comments
 (0)