Skip to content

Commit 8a3e320

Browse files
committed
Fix ignorable agent lifecycle noise
1 parent 110a794 commit 8a3e320

4 files changed

Lines changed: 65 additions & 5 deletions

File tree

apps/easypid/src/app/(app)/_layout.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,6 @@ export default function AppLayout() {
152152
<Stack.Screen name="pinConfirmation" options={headerNormalOptions} />
153153
<Stack.Screen name="pinLocked" options={headerNormalOptions} />
154154
<Stack.Screen name="trust" options={headerNormalOptions} />
155-
<Stack.Screen name="pidSetup" />
156155
<Stack.Screen name="inbox" options={headerNormalOptions} />
157156
</Stack>
158157
</ParadymWalletSdk.AppProvider>

packages/sdk/src/ParadymWalletSdk.tsx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ import { KeychainError } from './secure/error/KeychainError'
5858
import { deleteCredential } from './storage/credentials'
5959
import type { TrustMechanismConfiguration } from './trust/trustMechanism'
6060
import type { DistributedOmit } from './types'
61+
import { isIgnorableAgentLifecycleError } from './utils/agentLifecycleError'
6162
import { reset } from './utils/reset'
6263

6364
export type ParadymWalletSdkResult<T extends Record<string, unknown> = Record<string, unknown>> =
@@ -483,10 +484,20 @@ function useSecureUnlockState(configuration: SetupParadymWalletSdkOptions): Secu
483484
disableBiometricUnlock,
484485
reinitialize,
485486
lock: async () => {
486-
await paradym.shutdown()
487+
const unlockedParadym = paradym
488+
487489
setParadym(undefined)
490+
setWalletKey(undefined)
488491
setState('locked')
489492
setUnlockMethod(undefined)
493+
494+
try {
495+
await unlockedParadym.shutdown()
496+
} catch (error) {
497+
if (!isIgnorableAgentLifecycleError(error)) {
498+
throw error
499+
}
500+
}
490501
},
491502
}
492503
}

packages/sdk/src/providers/WalletJsonStoreProvider.tsx

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
RepositoryEventTypes,
88
} from '@credo-ts/core'
99
import { createContext, useContext, useEffect, useState } from 'react'
10+
import { isIgnorableAgentLifecycleError } from '../utils/agentLifecycleError'
1011

1112
type WalletJsonStoreState = {
1213
jsonRecords: GenericRecord[]
@@ -41,12 +42,27 @@ export const WalletJsonStoreProvider: React.FC<Props> = ({ agent, children, reco
4142
})
4243

4344
useEffect(() => {
45+
let cancelled = false
46+
4447
const fetchRecords = async () => {
45-
const records = await Promise.all(recordIds.map((id) => agent.genericRecords.findById(id)))
46-
const validRecords = records.filter((record): record is GenericRecord => record !== null)
47-
setState({ jsonRecords: validRecords, isLoading: false })
48+
try {
49+
const records = await Promise.all(recordIds.map((id) => agent.genericRecords.findById(id)))
50+
if (cancelled) return
51+
52+
const validRecords = records.filter((record): record is GenericRecord => record !== null)
53+
setState({ jsonRecords: validRecords, isLoading: false })
54+
} catch (error) {
55+
if (!cancelled && !isIgnorableAgentLifecycleError(error)) {
56+
console.error(error)
57+
}
58+
}
4859
}
60+
4961
void fetchRecords()
62+
63+
return () => {
64+
cancelled = true
65+
}
5066
}, [agent, recordIds])
5167

5268
useEffect(() => {
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// These teardown errors are bridged from native code and have not been observed to expose
2+
// a stable JS class or name, so narrow message matching is the most reliable wallet-side check.
3+
const ignorableAgentLifecycleErrorMessages = [
4+
'closed pool',
5+
'error acquiring pool connection',
6+
'attempted to acquire a connection on a closed pool',
7+
'invalid resource handle',
8+
'error details have already been overwritten on the native side',
9+
]
10+
11+
const collectErrorMessages = (error: unknown): string[] => {
12+
if (!error) return []
13+
14+
if (typeof error === 'string') {
15+
return [error]
16+
}
17+
18+
if (error instanceof Error) {
19+
const cause = 'cause' in error ? (error as Error & { cause?: unknown }).cause : undefined
20+
return [error.message, ...collectErrorMessages(cause)]
21+
}
22+
23+
if (typeof error === 'object' && 'message' in error && typeof error.message === 'string') {
24+
return [error.message]
25+
}
26+
27+
return []
28+
}
29+
30+
export const isIgnorableAgentLifecycleError = (error: unknown) => {
31+
return collectErrorMessages(error).some((message) =>
32+
ignorableAgentLifecycleErrorMessages.some((snippet) => message.toLowerCase().includes(snippet))
33+
)
34+
}

0 commit comments

Comments
 (0)