Skip to content

Commit a6c5592

Browse files
authored
Improve connect errors (#528)
* Improve connect errors * Linter * Fix new error handling in passkey-list
1 parent 7c27575 commit a6c5592

16 files changed

Lines changed: 344 additions & 189 deletions

packages/connect-react/src/components/append/AppendAfterErrorScreen.tsx

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { ExcludeCredentialsMatchError, PasskeyChallengeCancelledError } from '@corbado/web-core';
1+
import type { ConnectError } from '@corbado/web-core';
2+
import { ConnectErrorType } from '@corbado/web-core';
23
import log from 'loglevel';
34
import React, { useCallback, useState } from 'react';
45

@@ -25,15 +26,15 @@ const AppendAfterErrorScreen = ({ attestationOptions }: { attestationOptions: st
2526
setErrorMessage(undefined);
2627
const res = await getConnectService().completeAppend(attestationOptions);
2728
if (res.err) {
28-
if (res.val instanceof ExcludeCredentialsMatchError) {
29-
return handleSituation(AppendSituationCode.ClientExcludeCredentialsMatch);
29+
if (res.val.type === ConnectErrorType.ExcludeCredentialsMatch) {
30+
return handleSituation(AppendSituationCode.ClientExcludeCredentialsMatch, res.val);
3031
}
3132

32-
if (res.val instanceof PasskeyChallengeCancelledError) {
33-
return handleSituation(AppendSituationCode.ClientPasskeyOperationCancelled);
33+
if (res.val.type === ConnectErrorType.Cancel) {
34+
return handleSituation(AppendSituationCode.ClientPasskeyOperationCancelled, res.val);
3435
}
3536

36-
return handleSituation(AppendSituationCode.CboApiNotAvailablePostAuthenticator);
37+
return handleSituation(AppendSituationCode.CboApiNotAvailablePostAuthenticator, res.val);
3738
}
3839

3940
setLoading(false);
@@ -43,7 +44,7 @@ const AppendAfterErrorScreen = ({ attestationOptions }: { attestationOptions: st
4344
});
4445
};
4546

46-
const handleSituation = (situationCode: AppendSituationCode) => {
47+
const handleSituation = (situationCode: AppendSituationCode, error?: ConnectError) => {
4748
log.debug(`situation: ${situationCode}`);
4849

4950
const message = getAppendErrorMessage(situationCode);
@@ -55,14 +56,14 @@ const AppendAfterErrorScreen = ({ attestationOptions }: { attestationOptions: st
5556
case AppendSituationCode.CtApiNotAvailablePreAuthenticator:
5657
case AppendSituationCode.CboApiNotAvailablePreAuthenticator:
5758
case AppendSituationCode.CboApiNotAvailablePostAuthenticator:
58-
void handleErrorHard(situationCode, false);
59+
void handleErrorHard(situationCode, false, error);
5960
break;
6061
case AppendSituationCode.ClientPasskeyOperationCancelled:
6162
setLoading(false);
62-
void handleErrorSoft(situationCode, true, true);
63+
void handleErrorSoft(situationCode, true, true, error);
6364
break;
6465
case AppendSituationCode.ClientExcludeCredentialsMatch:
65-
void handleCredentialExistsError();
66+
void handleCredentialExistsError(error);
6667
break;
6768
case AppendSituationCode.ExplicitSkipByUser:
6869
void handleSkip(situationCode, true);

packages/connect-react/src/components/append/AppendInitScreen.tsx

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { ExcludeCredentialsMatchError, PasskeyChallengeCancelledError } from '@corbado/web-core';
1+
import type { ConnectError } from '@corbado/web-core';
2+
import { ConnectErrorType } from '@corbado/web-core';
23
import log from 'loglevel';
34
import React, { useCallback, useEffect, useRef, useState } from 'react';
45

@@ -80,11 +81,11 @@ const AppendInitScreen = () => {
8081

8182
const res = await getConnectService().appendInit(ac);
8283
if (res.err) {
83-
if (res.val.ignore) {
84+
if (res.val.type === ConnectErrorType.Cancel) {
8485
return;
8586
}
8687

87-
return handleSituation(AppendSituationCode.CboApiNotAvailablePreAuthenticator);
88+
return handleSituation(AppendSituationCode.CboApiNotAvailablePreAuthenticator, res.val);
8889
}
8990

9091
// we load flags from backend first, then we override them with the ones that are specified in the component's config
@@ -107,11 +108,11 @@ const AppendInitScreen = () => {
107108

108109
const startAppendRes = await getConnectService().startAppend(appendToken, loadedMs, ac);
109110
if (startAppendRes.err) {
110-
if (startAppendRes.val.ignore) {
111+
if (startAppendRes.val.type === ConnectErrorType.Cancel) {
111112
return;
112113
}
113114

114-
return handleSituation(AppendSituationCode.CboApiNotAvailablePostAuthenticator);
115+
return handleSituation(AppendSituationCode.CboApiNotAvailablePostAuthenticator, startAppendRes.val);
115116
}
116117

117118
if (startAppendRes.val.attestationOptions === '') {
@@ -162,19 +163,19 @@ const AppendInitScreen = () => {
162163

163164
const res = await getConnectService().completeAppend(attestationOptions);
164165
if (res.err) {
165-
if (res.val instanceof ExcludeCredentialsMatchError) {
166-
return handleSituation(AppendSituationCode.ClientExcludeCredentialsMatch);
166+
if (res.val.type === ConnectErrorType.ExcludeCredentialsMatch) {
167+
return handleSituation(AppendSituationCode.ClientExcludeCredentialsMatch, res.val);
167168
}
168169

169-
if (res.val instanceof PasskeyChallengeCancelledError) {
170+
if (res.val.type === ConnectErrorType.Cancel) {
170171
if (showErrorIfCancelled) {
171-
return handleSituation(AppendSituationCode.ClientPasskeyOperationCancelled);
172+
return handleSituation(AppendSituationCode.ClientPasskeyOperationCancelled, res.val);
172173
} else {
173-
return handleSituation(AppendSituationCode.ClientPasskeyOperationCancelledSilent);
174+
return handleSituation(AppendSituationCode.ClientPasskeyOperationCancelledSilent, res.val);
174175
}
175176
}
176177

177-
return handleSituation(AppendSituationCode.CboApiNotAvailablePostAuthenticator);
178+
return handleSituation(AppendSituationCode.CboApiNotAvailablePostAuthenticator, res.val);
178179
}
179180

180181
setAppendLoading(false);
@@ -186,7 +187,7 @@ const AppendInitScreen = () => {
186187
[config, getConnectService, appendLoading, skipping],
187188
);
188189

189-
const handleSituation = async (situationCode: AppendSituationCode) => {
190+
const handleSituation = async (situationCode: AppendSituationCode, error?: ConnectError) => {
190191
log.debug(`situation: ${situationCode}`);
191192

192193
const message = getAppendErrorMessage(situationCode);
@@ -198,20 +199,20 @@ const AppendInitScreen = () => {
198199
case AppendSituationCode.CtApiNotAvailablePreAuthenticator:
199200
case AppendSituationCode.CboApiNotAvailablePreAuthenticator:
200201
case AppendSituationCode.CboApiNotAvailablePostAuthenticator:
201-
void handleErrorHard(situationCode, false);
202+
void handleErrorHard(situationCode, false, error);
202203

203204
statefulLoader.current.finishWithError();
204205
break;
205206
case AppendSituationCode.ClientPasskeyOperationCancelled:
206-
void handleErrorSoft(situationCode, true, true);
207+
void handleErrorSoft(situationCode, true, true, error);
207208
setAppendLoading(false);
208209
break;
209210
case AppendSituationCode.ClientPasskeyOperationCancelledSilent:
210-
void handleErrorSoft(situationCode, true, false);
211+
void handleErrorSoft(situationCode, true, false, error);
211212
setAppendLoading(false);
212213
break;
213214
case AppendSituationCode.ClientExcludeCredentialsMatch:
214-
void handleCredentialExistsError();
215+
void handleCredentialExistsError(error);
215216
setAppendLoading(false);
216217
break;
217218
case AppendSituationCode.DeniedByPartialRollout:

packages/connect-react/src/components/login-second-factor/InitScreen.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { PasskeyChallengeCancelledError, PasskeyLoginSource } from '@corbado/web-core';
1+
import { ConnectErrorType, PasskeyChallengeCancelledError, PasskeyLoginSource } from '@corbado/web-core';
22
import type { ConnectLoginStartRsp } from '@corbado/web-core/dist/api/v2';
33
import log from 'loglevel';
44
import React, { useEffect, useRef, useState } from 'react';
@@ -41,7 +41,7 @@ const InitScreen = () => {
4141
statefulLoader.current.start();
4242
const res = await getConnectService().loginInit(ac);
4343
if (res.err) {
44-
if (res.val.ignore) {
44+
if (res.val.type === ConnectErrorType.Cancel) {
4545
return;
4646
}
4747

@@ -75,7 +75,7 @@ const InitScreen = () => {
7575
ac,
7676
);
7777
if (resStart.err) {
78-
if (resStart.val.ignore) {
78+
if (resStart.val.type === ConnectErrorType.Cancel) {
7979
return;
8080
}
8181

packages/connect-react/src/components/login/LoginErrorScreenHard.tsx

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { PasskeyChallengeCancelledError, PasskeyLoginSource } from '@corbado/web-core';
1+
import type { ConnectError } from '@corbado/web-core';
2+
import { ConnectErrorType, PasskeyLoginSource } from '@corbado/web-core';
23
import log from 'loglevel';
34
import React, { useState } from 'react';
45

@@ -29,7 +30,7 @@ const LoginErrorScreenHard = ({ previousAssertionOptions }: Props) => {
2930
setLoading(true);
3031
const resStart = await getConnectService().loginStart(currentIdentifier, PasskeyLoginSource.ErrorHard, loadedMs);
3132
if (resStart.err) {
32-
return handleSituation(LoginSituationCode.CboApiNotAvailablePreAuthenticator);
33+
return handleSituation(LoginSituationCode.CboApiNotAvailablePreAuthenticator, resStart.val);
3334
}
3435

3536
if (resStart.val.assertionOptions.length === 0) {
@@ -39,22 +40,22 @@ const LoginErrorScreenHard = ({ previousAssertionOptions }: Props) => {
3940
message: resStart.val.fallbackOperationError.error?.message ?? null,
4041
};
4142

42-
return handleSituation(LoginSituationCode.CboApiFallbackOperationError, data);
43+
return handleSituation(LoginSituationCode.CboApiFallbackOperationError, undefined, data);
4344
}
4445

4546
setAssertionOptions(resStart.val.assertionOptions);
4647

4748
const resFinish = await getConnectService().loginContinue(resStart.val);
4849
if (resFinish.err) {
49-
if (resFinish.val instanceof PasskeyChallengeCancelledError) {
50+
if (resFinish.val.type === ConnectErrorType.Cancel) {
5051
if (hardErrorCount >= 3) {
51-
return handleSituation(LoginSituationCode.ClientPasskeyOperationCancelledTooManyTimes);
52+
return handleSituation(LoginSituationCode.ClientPasskeyOperationCancelledTooManyTimes, resFinish.val);
5253
}
5354

54-
return handleSituation(LoginSituationCode.ClientPasskeyOperationCancelled);
55+
return handleSituation(LoginSituationCode.ClientPasskeyOperationCancelled, resFinish.val);
5556
}
5657

57-
return handleSituation(LoginSituationCode.CboApiNotAvailablePostAuthenticator);
58+
return handleSituation(LoginSituationCode.CboApiNotAvailablePostAuthenticator, resFinish.val);
5859
}
5960

6061
setLoading(false);
@@ -66,8 +67,8 @@ const LoginErrorScreenHard = ({ previousAssertionOptions }: Props) => {
6667
}
6768
};
6869

69-
const handleSituation = (situationCode: LoginSituationCode, data?: unknown) => {
70-
const messageCode = `situation: ${situationCode}`;
70+
const handleSituation = (situationCode: LoginSituationCode, error?: ConnectError, data?: unknown) => {
71+
const messageCode = `situation: ${situationCode} ${error?.track()}`;
7172
log.debug(messageCode);
7273

7374
const identifier = currentIdentifier;

packages/connect-react/src/components/login/LoginErrorScreenSoft.tsx

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { PasskeyChallengeCancelledError, PasskeyLoginSource } from '@corbado/web-core';
1+
import type { ConnectError } from '@corbado/web-core';
2+
import { ConnectErrorType, PasskeyLoginSource } from '@corbado/web-core';
23
import log from 'loglevel';
34
import React, { useState } from 'react';
45

@@ -28,7 +29,7 @@ const LoginErrorScreenSoft = ({ previousAssertionOptions }: Props) => {
2829
setLoading(true);
2930
const resStart = await getConnectService().loginStart(currentIdentifier, PasskeyLoginSource.ErrorSoft, loadedMs);
3031
if (resStart.err) {
31-
return handleSituation(LoginSituationCode.CboApiNotAvailablePreAuthenticator);
32+
return handleSituation(LoginSituationCode.CboApiNotAvailablePreAuthenticator, resStart.val);
3233
}
3334

3435
if (resStart.val.assertionOptions.length === 0) {
@@ -38,16 +39,20 @@ const LoginErrorScreenSoft = ({ previousAssertionOptions }: Props) => {
3839
message: resStart.val.fallbackOperationError.error?.message ?? null,
3940
};
4041

41-
return handleSituation(LoginSituationCode.CboApiFallbackOperationError, data);
42+
return handleSituation(LoginSituationCode.CboApiFallbackOperationError, undefined, data);
4243
}
4344

4445
const resFinish = await getConnectService().loginContinue(resStart.val);
4546
if (resFinish.err) {
46-
if (resFinish.val instanceof PasskeyChallengeCancelledError) {
47-
return handleSituation(LoginSituationCode.ClientPasskeyOperationCancelled, resStart.val.assertionOptions);
47+
if (resFinish.val.type === ConnectErrorType.Cancel) {
48+
return handleSituation(
49+
LoginSituationCode.ClientPasskeyOperationCancelled,
50+
resFinish.val,
51+
resStart.val.assertionOptions,
52+
);
4853
}
4954

50-
return handleSituation(LoginSituationCode.CboApiNotAvailablePostAuthenticator);
55+
return handleSituation(LoginSituationCode.CboApiNotAvailablePostAuthenticator, resFinish.val);
5156
}
5257

5358
try {
@@ -58,8 +63,8 @@ const LoginErrorScreenSoft = ({ previousAssertionOptions }: Props) => {
5863
}
5964
};
6065

61-
const handleSituation = (situationCode: LoginSituationCode, data?: unknown) => {
62-
const messageCode = `situation: ${situationCode}`;
66+
const handleSituation = (situationCode: LoginSituationCode, error?: ConnectError, data?: unknown) => {
67+
const messageCode = `situation: ${situationCode} ${error?.track()}`;
6368
log.debug(messageCode);
6469

6570
const identifier = currentIdentifier;

packages/connect-react/src/components/login/LoginHybridScreen.tsx

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { PasskeyChallengeCancelledError } from '@corbado/web-core';
1+
import type { ConnectError } from '@corbado/web-core';
2+
import { ConnectErrorType } from '@corbado/web-core';
23
import type { ConnectLoginStartRsp } from '@corbado/web-core/dist/api/v2';
34
import log from 'loglevel';
45
import React, { useCallback, useState } from 'react';
@@ -23,11 +24,11 @@ const LoginHybridScreen = (resStart: ConnectLoginStartRsp) => {
2324
setLoading(true);
2425
const res = await getConnectService().loginContinue(resStart);
2526
if (res.err) {
26-
if (res.val instanceof PasskeyChallengeCancelledError) {
27-
return handleSituation(LoginSituationCode.ClientPasskeyOperationCancelled);
27+
if (res.val.type === ConnectErrorType.Cancel) {
28+
return handleSituation(LoginSituationCode.ClientPasskeyOperationCancelled, res.val);
2829
}
2930

30-
return handleSituation(LoginSituationCode.CboApiNotAvailablePostAuthenticator);
31+
return handleSituation(LoginSituationCode.CboApiNotAvailablePostAuthenticator, res.val);
3132
}
3233

3334
try {
@@ -37,8 +38,8 @@ const LoginHybridScreen = (resStart: ConnectLoginStartRsp) => {
3738
}
3839
}, [getConnectService, config, navigateToScreen, currentIdentifier, loading]);
3940

40-
const handleSituation = (situationCode: LoginSituationCode) => {
41-
const messageCode = `situation: ${situationCode}`;
41+
const handleSituation = (situationCode: LoginSituationCode, error?: ConnectError) => {
42+
const messageCode = `situation: ${situationCode} ${error?.track()}`;
4243
log.debug(messageCode);
4344

4445
const identifier = currentIdentifier;

0 commit comments

Comments
 (0)