Skip to content

Commit

Permalink
chore: init withRetries helper
Browse files Browse the repository at this point in the history
  • Loading branch information
kravetsone committed Jan 1, 2025
1 parent 6fc2338 commit 25cf88b
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 19 deletions.
26 changes: 17 additions & 9 deletions src/bot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import type {
} from "@gramio/types";
import debug from "debug";
import { Inspectable } from "inspectable";
import { withRetries } from "utils.ts";
import { ErrorKind, TelegramError } from "./errors.js";
// import type { Filters } from "./filters";
import { Plugin } from "./plugin.js";
Expand Down Expand Up @@ -1224,11 +1225,14 @@ export class Bot<
await this.init();

if (!webhook) {
await this.api.deleteWebhook({
drop_pending_updates: dropPendingUpdates,
});
const r = await withRetries(() =>
this.api.deleteWebhook({
drop_pending_updates: dropPendingUpdates,
suppress: true,
}),
);

await this.updates.startPolling({
this.updates.startPolling({
allowed_updates: allowedUpdates,
});

Expand All @@ -1244,11 +1248,15 @@ export class Bot<

if (this.updates.isStarted) this.updates.stopPolling();

await this.api.setWebhook({
...webhook,
drop_pending_updates: dropPendingUpdates,
allowed_updates: allowedUpdates,
});
// TODO: do we need await it?
withRetries(() =>
this.api.setWebhook({
...webhook,
drop_pending_updates: dropPendingUpdates,
allowed_updates: allowedUpdates,
suppress: true,
}),
);

this.runImmutableHooks("onStart", {
plugins: this.dependencies,
Expand Down
5 changes: 1 addition & 4 deletions src/queue.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import type { TelegramUpdate } from "@gramio/types";

// cant use node:timers/promises because possible browser usage...
export const sleep = (ms: number) =>
new Promise((resolve) => setTimeout(resolve, ms));
import { sleep } from "./utils.ts";

// concurrent queue (like event loop) for managing updates with graceful shutdown support
export class UpdateQueue<Data = TelegramUpdate> {
Expand Down
2 changes: 1 addition & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ export type SuppressedAPIMethodParams<Method extends keyof APIMethods> =
: MaybeSuppressedParams<Method, true>;

/** Type that return MaybeSuppressed API method ReturnType */
type MaybeSuppressedReturn<
export type MaybeSuppressedReturn<
Method extends keyof APIMethods,
IsSuppressed extends boolean | undefined = undefined,
> = true extends IsSuppressed
Expand Down
5 changes: 3 additions & 2 deletions src/updates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ import type { APIMethodParams, TelegramUpdate } from "@gramio/types";
import type { CaughtMiddlewareHandler } from "middleware-io";
import { Composer } from "./composer.js";
import { TelegramError } from "./errors.js";
import { UpdateQueue, sleep } from "./queue.js";
import { UpdateQueue } from "./queue.js";
import type { AnyBot } from "./types.js";
import { sleep } from "./utils.ts";

export class Updates {
private readonly bot: AnyBot;
Expand Down Expand Up @@ -67,7 +68,7 @@ export class Updates {
}
}
/** @deprecated use bot.start instead @internal */
async startPolling(params: APIMethodParams<"getUpdates"> = {}) {
startPolling(params: APIMethodParams<"getUpdates"> = {}) {
if (this.isStarted) throw new Error("[UPDATES] Polling already started!");

this.isStarted = true;
Expand Down
41 changes: 41 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import type { APIMethodReturn, APIMethods } from "@gramio/types";
import { TelegramError } from "./errors.ts";
import type {
MaybeSuppressedReturn,
SuppressedAPIMethodReturn,
} from "./types.ts";

// cant use node:timers/promises because possible browser usage...
export const sleep = (ms: number) =>
new Promise((resolve) => setTimeout(resolve, ms));

// TODO: improve types. suppress should be required
export async function withRetries<
Result extends Promise<unknown>,
Mode extends "suppress" | "rethrow" = "suppress",
>(
resultPromise: () => Result,
mode: Mode = "suppress" as Mode,
): Promise<Result> {
let result = await resultPromise().catch((error) => error);

while (result instanceof TelegramError) {
const retryAfter = result.payload?.retry_after;
console.log(result.method, retryAfter);

if (retryAfter) {
await sleep(retryAfter * 1000);
result = await resultPromise();
} else {
if (mode === "rethrow") throw result;

// TODO: hard conditional typings. fix later
// @ts-expect-error
return result;
}
}

// TODO: find why it miss types. but it works as expected
// @ts-expect-error this is fine
return result;
}
6 changes: 3 additions & 3 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
{
"compilerOptions": {
"lib": ["ESNext"],
"module": "ESNext",
"module": "NodeNext",
"target": "ESNext",
"moduleResolution": "Bundler",
"moduleResolution": "NodeNext",
"esModuleInterop": true,
/* Linting */
"skipLibCheck": true,
"strict": true,
"noFallthroughCasesInSwitch": true,
"forceConsistentCasingInFileNames": true,

"composite": true,
"baseUrl": "./src",
"rootDir": "./src",
Expand Down

0 comments on commit 25cf88b

Please sign in to comment.