APP-2977: Handle AppView polling errors (#11590)
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
import {describe, expect, it, jest} from '@jest/globals'
|
||||
|
||||
import {until} from './until'
|
||||
|
||||
describe('until', () => {
|
||||
it('passes attempt errors to the condition', async () => {
|
||||
const error = new Error('failed')
|
||||
const fn = jest
|
||||
.fn<() => Promise<string>>()
|
||||
.mockRejectedValueOnce(error)
|
||||
.mockResolvedValue('ready')
|
||||
const cond = jest.fn((value: string | undefined) => value === 'ready')
|
||||
|
||||
await expect(until(2, 0, cond, fn)).resolves.toBe(true)
|
||||
expect(fn).toHaveBeenCalledTimes(2)
|
||||
expect(cond).toHaveBeenNthCalledWith(1, undefined, error)
|
||||
expect(cond).toHaveBeenNthCalledWith(2, 'ready', undefined)
|
||||
})
|
||||
|
||||
it('returns false when every attempt rejects', async () => {
|
||||
const fn = jest
|
||||
.fn<() => Promise<string>>()
|
||||
.mockRejectedValue(new Error('failed'))
|
||||
const cond = jest.fn((_value: string | undefined) => false)
|
||||
|
||||
await expect(until(2, 0, cond, fn)).resolves.toBe(false)
|
||||
expect(fn).toHaveBeenCalledTimes(2)
|
||||
expect(cond).toHaveBeenCalledTimes(2)
|
||||
})
|
||||
|
||||
it('can stop when an attempt rejects', async () => {
|
||||
const error = new Error('failed')
|
||||
const fn = jest.fn<() => Promise<string>>().mockRejectedValue(error)
|
||||
const cond = jest.fn(
|
||||
(_value: string | undefined, err: unknown) => err === error,
|
||||
)
|
||||
|
||||
await expect(until(2, 0, cond, fn)).resolves.toBe(true)
|
||||
expect(fn).toHaveBeenCalledTimes(1)
|
||||
expect(cond).toHaveBeenCalledWith(undefined, error)
|
||||
})
|
||||
})
|
||||
@@ -1,9 +1,12 @@
|
||||
import {timeout} from './timeout'
|
||||
|
||||
/**
|
||||
* Retries an async operation until its result or error matches `cond`.
|
||||
*/
|
||||
export async function until<T>(
|
||||
retries: number,
|
||||
delay: number,
|
||||
cond: (v: T, err: any) => boolean,
|
||||
cond: (v: T | undefined, err: unknown) => boolean,
|
||||
fn: () => Promise<T>,
|
||||
): Promise<boolean> {
|
||||
while (retries > 0) {
|
||||
@@ -12,10 +15,8 @@ export async function until<T>(
|
||||
if (cond(v, undefined)) {
|
||||
return true
|
||||
}
|
||||
} catch (e: any) {
|
||||
// TODO: change the type signature of cond to accept undefined
|
||||
// however this breaks every existing usage of until -sfn
|
||||
if (cond(undefined as unknown as T, e)) {
|
||||
} catch (err) {
|
||||
if (cond(undefined, err)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,7 +141,10 @@ function createListItem({
|
||||
async function whenAppViewReady(
|
||||
client: Client,
|
||||
uri: string,
|
||||
fn: (res?: app.bsky.graph.getStarterPack.$OutputBody) => boolean,
|
||||
fn: (
|
||||
res: app.bsky.graph.getStarterPack.$OutputBody | undefined,
|
||||
err: unknown,
|
||||
) => boolean,
|
||||
) {
|
||||
await until(
|
||||
5, // 5 tries
|
||||
|
||||
Reference in New Issue
Block a user