Skip to content

Commit

Permalink
chore: improve error handling (#3188)
Browse files Browse the repository at this point in the history
Co-authored-by: tomiir <rocchitomas@gmail.com>
  • Loading branch information
magiziz and tomiir authored Nov 6, 2024
1 parent db30b41 commit 69e8bde
Show file tree
Hide file tree
Showing 9 changed files with 97 additions and 24 deletions.
24 changes: 24 additions & 0 deletions .changeset/bright-plants-speak.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
'@reown/appkit-adapter-ethers5': patch
'@reown/appkit-adapter-ethers': patch
'@reown/appkit-adapter-solana': patch
'@reown/appkit-adapter-wagmi': patch
'@reown/appkit-utils': patch
'@reown/appkit': patch
'@apps/demo': patch
'@apps/gallery': patch
'@apps/laboratory': patch
'@reown/appkit-adapter-polkadot': patch
'@reown/appkit-cdn': patch
'@reown/appkit-common': patch
'@reown/appkit-core': patch
'@reown/appkit-experimental': patch
'@reown/appkit-polyfills': patch
'@reown/appkit-scaffold-ui': patch
'@reown/appkit-siwe': patch
'@reown/appkit-siwx': patch
'@reown/appkit-ui': patch
'@reown/appkit-wallet': patch
---

Improved error handling for auth and universal provider connectors.
2 changes: 1 addition & 1 deletion packages/adapters/ethers/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1170,7 +1170,7 @@ export class EthersAdapter {
this.authProvider = W3mFrameProviderSingleton.getInstance({
projectId,
onTimeout: () => {
AlertController.open(ErrorUtil.ALERT_ERRORS.INVALID_APP_CONFIGURATION_SOCIALS, 'error')
AlertController.open(ErrorUtil.ALERT_ERRORS.SOCIALS_TIMEOUT, 'error')
}
})

Expand Down
2 changes: 1 addition & 1 deletion packages/adapters/ethers5/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1159,7 +1159,7 @@ export class Ethers5Adapter {
this.authProvider = W3mFrameProviderSingleton.getInstance({
projectId,
onTimeout: () => {
AlertController.open(ErrorUtil.ALERT_ERRORS.INVALID_APP_CONFIGURATION_SOCIALS, 'error')
AlertController.open(ErrorUtil.ALERT_ERRORS.SOCIALS_TIMEOUT, 'error')
}
})

Expand Down
2 changes: 1 addition & 1 deletion packages/adapters/solana/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -631,7 +631,7 @@ export class SolanaAdapter implements ChainAdapter {
projectId: opts.projectId,
chainId: withSolanaNamespace(this.appKit?.getCaipNetwork(this.chainNamespace)?.id),
onTimeout: () => {
AlertController.open(ErrorUtil.ALERT_ERRORS.INVALID_APP_CONFIGURATION_SOCIALS, 'error')
AlertController.open(ErrorUtil.ALERT_ERRORS.SOCIALS_TIMEOUT, 'error')
}
})

Expand Down
2 changes: 1 addition & 1 deletion packages/adapters/wagmi/src/connectors/AuthConnector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ export function authConnector(parameters: AuthParameters) {
this.provider = W3mFrameProviderSingleton.getInstance({
projectId: parameters.options.projectId,
onTimeout: () => {
AlertController.open(ErrorUtil.ALERT_ERRORS.INVALID_APP_CONFIGURATION_SOCIALS, 'error')
AlertController.open(ErrorUtil.ALERT_ERRORS.SOCIALS_TIMEOUT, 'error')
}
})
}
Expand Down
20 changes: 15 additions & 5 deletions packages/appkit-utils/src/ErrorUtil.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
export const ErrorUtil = {
UniversalProviderErrors: {
UNAUTHORIZED_DOMAIN_NOT_ALLOWED: 'Unauthorized: origin not allowed'
UNAUTHORIZED_DOMAIN_NOT_ALLOWED: {
message: 'Unauthorized: origin not allowed',
alertErrorKey: 'INVALID_APP_CONFIGURATION'
},
JWT_VALIDATION_ERROR: {
message: 'JWT validation error: JWT Token is not yet valid',
alertErrorKey: 'JWT_TOKEN_NOT_VALID'
}
},
ALERT_ERRORS: {
SWITCH_NETWORK_NOT_FOUND: {
Expand All @@ -15,12 +22,15 @@ export const ErrorUtil = {
isSafe() ? window.origin : 'unknown'
} not found on Allowlist - update configuration`
},
INVALID_APP_CONFIGURATION_SOCIALS: {
SOCIALS_TIMEOUT: {
shortMessage: 'Invalid App Configuration',
longMessage: () =>
`Origin ${
isSafe() ? window.origin : 'unknown'
} not found on Allowlist - update configuration to enable social login`
'There was an issue loading the embedded wallet. Please verify that your domain is allowed at cloud.reown.com'
},
JWT_TOKEN_NOT_VALID: {
shortMessage: 'Session Expired',
longMessage:
'Invalid session found on UniversalProvider - please check your time settings and connect again'
},
PROJECT_ID_NOT_CONFIGURED: {
shortMessage: 'Project ID Not Configured',
Expand Down
7 changes: 4 additions & 3 deletions packages/appkit-utils/src/LoggerUtil.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { generatePlatformLogger, getDefaultLoggerOptions } from '@walletconnect/logger'

export const LoggerUtil = {
createLogger(onError: (error: Error, ...args: unknown[]) => void, level = 'error') {
createLogger(onError: (error?: Error, ...args: unknown[]) => void, level = 'error') {
const loggerOptions = getDefaultLoggerOptions({
level
})
Expand All @@ -14,11 +14,12 @@ export const LoggerUtil = {
for (const arg of args) {
if (arg instanceof Error) {
onError(arg, ...args)
break

return
}
}

onError(new Error(), ...args)
onError(undefined, ...args)
}

return logger
Expand Down
29 changes: 27 additions & 2 deletions packages/appkit/src/tests/universal-adapter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import { UniversalAdapterClient } from '../universal-adapter'
import { mockOptions } from './mocks/Options'
import mockProvider from './mocks/UniversalProvider'
import type UniversalProvider from '@walletconnect/universal-provider'
import { ChainController } from '@reown/appkit-core'
import { AlertController, ChainController } from '@reown/appkit-core'
import { ProviderUtil } from '../store/index.js'
import { CaipNetworksUtil, ConstantsUtil, PresetsUtil } from '@reown/appkit-utils'
import { CaipNetworksUtil, ConstantsUtil, ErrorUtil, PresetsUtil } from '@reown/appkit-utils'
import mockAppKit from './mocks/AppKit'
import type { CaipNetwork } from '@reown/appkit-common'

Expand All @@ -21,6 +21,8 @@ const mockOptionsExtended = {
defaultNetwork: mainnet
}

vi.mock('@reown/appkit-core')

describe('UniversalAdapter', () => {
let universalAdapter: UniversalAdapterClient

Expand Down Expand Up @@ -205,4 +207,27 @@ describe('UniversalAdapter', () => {
])
})
})

describe('UniversalAdapter - Alert Errors', () => {
it('should handle alert errors based on error messages', () => {
const errors = [
{
alert: ErrorUtil.ALERT_ERRORS.INVALID_APP_CONFIGURATION,
message:
'Error: WebSocket connection closed abnormally with code: 3000 (Unauthorized: origin not allowed)'
},
{
alert: ErrorUtil.ALERT_ERRORS.JWT_TOKEN_NOT_VALID,
message:
'WebSocket connection closed abnormally with code: 3000 (JWT validation error: JWT Token is not yet valid:)'
}
]

for (const { alert, message } of errors) {
// @ts-expect-error
universalAdapter.handleAlertError(new Error(message))
expect(AlertController.open).toHaveBeenCalledWith(alert, 'error')
}
})
})
})
33 changes: 23 additions & 10 deletions packages/appkit/src/universal-adapter/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export class UniversalAdapterClient {

public adapterType: AdapterType = 'universal'

public reportErrors = true
public reportedAlertErrors: Record<string, boolean> = {}

public constructor(options: AppKitOptionsWithCaipNetworks) {
const { siweConfig, metadata } = options
Expand Down Expand Up @@ -405,17 +405,31 @@ export class UniversalAdapterClient {
return this.walletConnectProviderInitPromise
}

private async initWalletConnectProvider(projectId: string) {
const logger = LoggerUtil.createLogger((err, ...args) => {
if (err.message.includes(ErrorUtil.UniversalProviderErrors.UNAUTHORIZED_DOMAIN_NOT_ALLOWED)) {
if (this.reportErrors) {
AlertController.open(ErrorUtil.ALERT_ERRORS.INVALID_APP_CONFIGURATION, 'error')
this.reportErrors = false
}
private handleAlertError(error: Error) {
const matchedUniversalProviderError = Object.entries(ErrorUtil.UniversalProviderErrors).find(
([, { message }]) => error.message.includes(message)
)

return
const [errorKey, errorValue] = matchedUniversalProviderError ?? []

const { message, alertErrorKey } = errorValue ?? {}

if (errorKey && message && !this.reportedAlertErrors[errorKey]) {
const alertError =
ErrorUtil.ALERT_ERRORS[alertErrorKey as keyof typeof ErrorUtil.ALERT_ERRORS]

if (alertError) {
AlertController.open(alertError, 'error')
this.reportedAlertErrors[errorKey] = true
}
}
}

private async initWalletConnectProvider(projectId: string) {
const logger = LoggerUtil.createLogger((error, ...args) => {
if (error) {
this.handleAlertError(error)
}
// eslint-disable-next-line no-console
console.error(...args)
})
Expand All @@ -432,7 +446,6 @@ export class UniversalAdapterClient {
}

this.walletConnectProvider = await UniversalProvider.init(walletConnectProviderOptions)

await this.checkActiveWalletConnectProvider()
}

Expand Down

0 comments on commit 69e8bde

Please sign in to comment.