diff --git a/packages/interop/src/json.spec.ts b/packages/interop/src/json.spec.ts index 4536faab..90e615ac 100644 --- a/packages/interop/src/json.spec.ts +++ b/packages/interop/src/json.spec.ts @@ -21,7 +21,7 @@ describe('@helia/verified-fetch - json', () => { await loadFixtureDataCar(controller, 'QmQJ8fxavY54CUsxMSx9aE9Rdcmvhx8awJK2jzJp4iAqCr-tokens.uniswap.org-2024-01-18.car') verifiedFetch = await createVerifiedFetch({ gateways: [`http://${controller.api.gatewayHost}:${controller.api.gatewayPort}`], - routers: [`http://${controller.api.gatewayHost}:${controller.api.gatewayPort}`] + routers: [] }) }) diff --git a/packages/verified-fetch/src/utils/walk-path.ts b/packages/verified-fetch/src/utils/walk-path.ts index be46fdf2..82db12e9 100644 --- a/packages/verified-fetch/src/utils/walk-path.ts +++ b/packages/verified-fetch/src/utils/walk-path.ts @@ -19,9 +19,20 @@ export async function walkPath (blockstore: ReadableStorage, path: string, optio const ipfsRoots: CID[] = [] let terminalElement: UnixFSEntry | undefined - for await (const entry of exporterWalk(path, blockstore, options)) { - ipfsRoots.push(entry.cid) - terminalElement = entry + try { + for await (const entry of exporterWalk(path, blockstore, options)) { + ipfsRoots.push(entry.cid) + terminalElement = entry + } + } catch (err: any) { + if (err.errors?.length > 0) { + for (const error of err.errors) { + if (error.code === 'ERR_NO_ROUTERS_AVAILABLE') { + throw error + } + } + } + throw err } if (terminalElement == null) { diff --git a/packages/verified-fetch/src/verified-fetch.ts b/packages/verified-fetch/src/verified-fetch.ts index 1bfccc83..0802b2bd 100644 --- a/packages/verified-fetch/src/verified-fetch.ts +++ b/packages/verified-fetch/src/verified-fetch.ts @@ -161,14 +161,19 @@ export class VerifiedFetch { return this.helia.blockstore } - let session = this.blockstoreSessions.get(key) + try { + let session = this.blockstoreSessions.get(key) - if (session == null) { - session = this.helia.blockstore.createSession(root, options) - this.blockstoreSessions.set(key, session) - } + if (session == null) { + session = this.helia.blockstore.createSession(root, options) + this.blockstoreSessions.set(key, session) + } - return session + return session + } catch (e) { + this.log.error('error creating blockstore session', e) + return this.helia.blockstore + } } /** @@ -289,6 +294,11 @@ export class VerifiedFetch { if (['ERR_NO_PROP', 'ERR_NO_TERMINAL_ELEMENT'].includes(err.code)) { return notFoundResponse(resource) } + if (err.code === 'ERR_NO_ROUTERS_AVAILABLE') { + // need to retry without sessions + // TODO: handle this better + return this.handleDagCbor({ resource, cid, path, accept, session: false, cacheKey, options }) + } this.log.error('error walking path %s', path, err) return badGatewayResponse(resource, 'Error walking path') @@ -357,6 +367,12 @@ export class VerifiedFetch { if (['ERR_NO_PROP', 'ERR_NO_TERMINAL_ELEMENT'].includes(err.code)) { return notFoundResponse(resource.toString()) } + + if (err.code === 'ERR_NO_ROUTERS_AVAILABLE') { + // need to retry without sessions + // TODO: handle this better + return this.handleDagPb({ resource, cid, path, cacheKey, session: false, options }) + } this.log.error('error walking path %s', path, err) return badGatewayResponse(resource.toString(), 'Error walking path')