@quiltt/react-native 4.2.2 → 4.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +37 -21
- package/package.json +4 -4
- package/src/components/QuilttConnector.tsx +36 -14
- package/src/utils/error/getErrorMessage.ts +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# @quiltt/react-native
|
|
2
2
|
|
|
3
|
+
## 4.2.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#355](https://github.com/quiltt/quiltt-js/pull/355) [`6d32f3e`](https://github.com/quiltt/quiltt-js/commit/6d32f3e40e7554c512ca63ef532d689d5485e10c) Thanks [@rubendinho](https://github.com/rubendinho)! - Improve error handling in React Native
|
|
8
|
+
|
|
9
|
+
- Updated dependencies [[`6d32f3e`](https://github.com/quiltt/quiltt-js/commit/6d32f3e40e7554c512ca63ef532d689d5485e10c)]:
|
|
10
|
+
- @quiltt/core@4.2.3
|
|
11
|
+
- @quiltt/react@4.2.3
|
|
12
|
+
|
|
3
13
|
## 4.2.2
|
|
4
14
|
|
|
5
15
|
### Patch Changes
|
package/dist/index.d.ts
CHANGED
|
@@ -14,14 +14,14 @@ declare const checkConnectorUrl: (connectorUrl: string, retryCount?: number) =>
|
|
|
14
14
|
*/
|
|
15
15
|
declare const handleOAuthUrl: (oauthUrl: URL | string | null | undefined) => void;
|
|
16
16
|
type QuilttConnectorProps = {
|
|
17
|
-
testId?: string;
|
|
18
17
|
connectorId: string;
|
|
19
18
|
connectionId?: string;
|
|
20
19
|
institution?: string;
|
|
21
20
|
oauthRedirectUrl: string;
|
|
21
|
+
testId?: string;
|
|
22
22
|
} & ConnectorSDKCallbacks;
|
|
23
23
|
declare const QuilttConnector: {
|
|
24
|
-
({
|
|
24
|
+
({ connectorId, connectionId, institution, oauthRedirectUrl, onEvent, onLoad, onExit, onExitSuccess, onExitAbort, onExitError, testId, }: QuilttConnectorProps): react_jsx_runtime.JSX.Element;
|
|
25
25
|
displayName: string;
|
|
26
26
|
};
|
|
27
27
|
|
package/dist/index.js
CHANGED
|
@@ -9,7 +9,7 @@ import { URL } from 'react-native-url-polyfill';
|
|
|
9
9
|
import { WebView } from 'react-native-webview';
|
|
10
10
|
import { generateStackTrace, makeBacktrace, getCauses } from '@honeybadger-io/core/build/src/util';
|
|
11
11
|
|
|
12
|
-
var version = "4.2.
|
|
12
|
+
var version = "4.2.3";
|
|
13
13
|
|
|
14
14
|
// Custom Error Reporter to avoid hooking into or colliding with a client's Honeybadger singleton
|
|
15
15
|
const notifier = {
|
|
@@ -91,8 +91,8 @@ class ErrorReporter {
|
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
const getErrorMessage = (responseStatus, error)=>{
|
|
94
|
-
if (error) return `An error occurred while checking the
|
|
95
|
-
return responseStatus ? `
|
|
94
|
+
if (error) return `An error occurred while checking the Connector URL: ${error?.name} \n${error?.message}`;
|
|
95
|
+
return responseStatus ? `An error occurred loading the Connector. Response status: ${responseStatus}` : 'An error occurred while checking the Connector URL';
|
|
96
96
|
};
|
|
97
97
|
|
|
98
98
|
/**
|
|
@@ -258,32 +258,45 @@ const errorReporter = new ErrorReporter(`${Platform.OS} ${Platform.Version}`);
|
|
|
258
258
|
const PREFLIGHT_RETRY_COUNT = 3;
|
|
259
259
|
const checkConnectorUrl = async (connectorUrl, retryCount = 0)=>{
|
|
260
260
|
let responseStatus;
|
|
261
|
-
let error;
|
|
262
261
|
try {
|
|
263
262
|
const response = await fetch(connectorUrl);
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
263
|
+
switch(response.status){
|
|
264
|
+
case 200:
|
|
265
|
+
return {
|
|
266
|
+
checked: true
|
|
267
|
+
};
|
|
268
|
+
case 400:
|
|
269
|
+
console.log('Invalid configuration');
|
|
270
|
+
return {
|
|
271
|
+
checked: true
|
|
272
|
+
};
|
|
273
|
+
case 404:
|
|
274
|
+
console.error('Connector not found');
|
|
275
|
+
return {
|
|
276
|
+
checked: true
|
|
277
|
+
};
|
|
278
|
+
default:
|
|
279
|
+
throw new Error('Connector URL is not routable.');
|
|
267
280
|
}
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
error = e;
|
|
273
|
-
console.error('Failed to connect to connector URL');
|
|
281
|
+
} catch (error) {
|
|
282
|
+
// Log error for debugging
|
|
283
|
+
console.error(error);
|
|
284
|
+
// Try again
|
|
274
285
|
if (retryCount < PREFLIGHT_RETRY_COUNT) {
|
|
275
286
|
const delay = 50 * 2 ** retryCount;
|
|
276
287
|
await new Promise((resolve)=>setTimeout(resolve, delay));
|
|
277
288
|
console.log(`Retrying connection... Attempt ${retryCount + 1}`);
|
|
278
289
|
return checkConnectorUrl(connectorUrl, retryCount + 1);
|
|
279
290
|
}
|
|
291
|
+
// Report error after retries exhausted
|
|
280
292
|
const errorMessage = getErrorMessage(responseStatus, error);
|
|
281
293
|
const errorToSend = error || new Error(errorMessage);
|
|
282
294
|
const context = {
|
|
283
295
|
connectorUrl,
|
|
284
296
|
responseStatus
|
|
285
297
|
};
|
|
286
|
-
|
|
298
|
+
await errorReporter.notify(errorToSend, context);
|
|
299
|
+
// Return errored preflight check
|
|
287
300
|
return {
|
|
288
301
|
checked: true,
|
|
289
302
|
error: errorMessage
|
|
@@ -322,7 +335,7 @@ const checkConnectorUrl = async (connectorUrl, retryCount = 0)=>{
|
|
|
322
335
|
}
|
|
323
336
|
}
|
|
324
337
|
};
|
|
325
|
-
const QuilttConnector = ({
|
|
338
|
+
const QuilttConnector = ({ connectorId, connectionId, institution, oauthRedirectUrl, onEvent, onLoad, onExit, onExitSuccess, onExitAbort, onExitError, testId })=>{
|
|
326
339
|
const webViewRef = useRef(null);
|
|
327
340
|
const { session } = useQuilttSession();
|
|
328
341
|
const [preFlightCheck, setPreFlightCheck] = useState({
|
|
@@ -496,7 +509,9 @@ const QuilttConnector = ({ testId, connectorId, connectionId, institution, oauth
|
|
|
496
509
|
handleQuilttEvent(url);
|
|
497
510
|
return false;
|
|
498
511
|
}
|
|
499
|
-
if (shouldRender(url))
|
|
512
|
+
if (shouldRender(url)) {
|
|
513
|
+
return true;
|
|
514
|
+
}
|
|
500
515
|
// Plaid set oauth url by doing window.location.href = url
|
|
501
516
|
// So we use `handleOAuthUrl` as a catch all and assume all url got to this step is Plaid OAuth url
|
|
502
517
|
handleOAuthUrl(url);
|
|
@@ -506,9 +521,11 @@ const QuilttConnector = ({ testId, connectorId, connectionId, institution, oauth
|
|
|
506
521
|
isQuilttEvent,
|
|
507
522
|
shouldRender
|
|
508
523
|
]);
|
|
509
|
-
if (!preFlightCheck.checked)
|
|
510
|
-
|
|
511
|
-
|
|
524
|
+
if (!preFlightCheck.checked) {
|
|
525
|
+
return /*#__PURE__*/ jsx(LoadingScreen, {
|
|
526
|
+
testId: "loading-screen"
|
|
527
|
+
});
|
|
528
|
+
}
|
|
512
529
|
if (preFlightCheck.error) {
|
|
513
530
|
return /*#__PURE__*/ jsx(ErrorScreen, {
|
|
514
531
|
testId: "error-screen",
|
|
@@ -521,10 +538,8 @@ const QuilttConnector = ({ testId, connectorId, connectionId, institution, oauth
|
|
|
521
538
|
return /*#__PURE__*/ jsx(AndroidSafeAreaView, {
|
|
522
539
|
testId: testId,
|
|
523
540
|
children: /*#__PURE__*/ jsx(WebView, {
|
|
524
|
-
testID: "webview",
|
|
525
541
|
ref: webViewRef,
|
|
526
542
|
// Plaid keeps sending window.location = 'about:srcdoc' and causes some noise in RN
|
|
527
|
-
// All whitelists are now handled in requestHandler, handleQuilttEvent and handleOAuthUrl
|
|
528
543
|
style: styles.webview,
|
|
529
544
|
originWhitelist: [
|
|
530
545
|
'*'
|
|
@@ -544,6 +559,7 @@ const QuilttConnector = ({ testId, connectorId, connectionId, institution, oauth
|
|
|
544
559
|
,
|
|
545
560
|
showsVerticalScrollIndicator: false,
|
|
546
561
|
showsHorizontalScrollIndicator: false,
|
|
562
|
+
testID: "webview",
|
|
547
563
|
...Platform.OS === 'ios' ? {
|
|
548
564
|
decelerationRate: 'normal',
|
|
549
565
|
keyboardDisplayRequiresUserAction: false,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quiltt/react-native",
|
|
3
|
-
"version": "4.2.
|
|
3
|
+
"version": "4.2.3",
|
|
4
4
|
"description": "React Native Components for Quiltt Connector",
|
|
5
5
|
"homepage": "https://github.com/quiltt/quiltt-js/tree/main/packages/react-native#readme",
|
|
6
6
|
"repository": {
|
|
@@ -30,14 +30,14 @@
|
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"@honeybadger-io/core": "6.6.0",
|
|
32
32
|
"lodash.debounce": "4.0.8",
|
|
33
|
-
"@quiltt/core": "4.2.
|
|
34
|
-
"@quiltt/react": "4.2.
|
|
33
|
+
"@quiltt/core": "4.2.3",
|
|
34
|
+
"@quiltt/react": "4.2.3"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"@biomejs/biome": "1.9.4",
|
|
38
38
|
"@types/base-64": "1.0.2",
|
|
39
39
|
"@types/lodash.debounce": "4.0.9",
|
|
40
|
-
"@types/node": "22.
|
|
40
|
+
"@types/node": "22.18.1",
|
|
41
41
|
"@types/react": "18.3.20",
|
|
42
42
|
"base-64": "1.0.0",
|
|
43
43
|
"bunchee": "6.3.4",
|
|
@@ -36,25 +36,41 @@ export const checkConnectorUrl = async (
|
|
|
36
36
|
let error: Error | undefined
|
|
37
37
|
try {
|
|
38
38
|
const response = await fetch(connectorUrl)
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
|
|
40
|
+
switch (response.status) {
|
|
41
|
+
case 200:
|
|
42
|
+
return { checked: true }
|
|
43
|
+
|
|
44
|
+
case 400:
|
|
45
|
+
console.log('Invalid configuration')
|
|
46
|
+
return { checked: true }
|
|
47
|
+
|
|
48
|
+
case 404:
|
|
49
|
+
console.error('Connector not found')
|
|
50
|
+
return { checked: true }
|
|
51
|
+
|
|
52
|
+
default:
|
|
53
|
+
throw new Error('Connector URL is not routable.')
|
|
42
54
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
error
|
|
46
|
-
console.error('Failed to connect to connector URL')
|
|
55
|
+
} catch (error) {
|
|
56
|
+
// Log error for debugging
|
|
57
|
+
console.error(error)
|
|
47
58
|
|
|
59
|
+
// Try again
|
|
48
60
|
if (retryCount < PREFLIGHT_RETRY_COUNT) {
|
|
49
61
|
const delay = 50 * 2 ** retryCount
|
|
50
62
|
await new Promise((resolve) => setTimeout(resolve, delay))
|
|
51
63
|
console.log(`Retrying connection... Attempt ${retryCount + 1}`)
|
|
52
64
|
return checkConnectorUrl(connectorUrl, retryCount + 1)
|
|
53
65
|
}
|
|
66
|
+
|
|
67
|
+
// Report error after retries exhausted
|
|
54
68
|
const errorMessage = getErrorMessage(responseStatus, error as Error)
|
|
55
69
|
const errorToSend = (error as Error) || new Error(errorMessage)
|
|
56
70
|
const context = { connectorUrl, responseStatus }
|
|
57
|
-
|
|
71
|
+
await errorReporter.notify(errorToSend, context)
|
|
72
|
+
|
|
73
|
+
// Return errored preflight check
|
|
58
74
|
return { checked: true, error: errorMessage }
|
|
59
75
|
}
|
|
60
76
|
}
|
|
@@ -99,15 +115,14 @@ export const handleOAuthUrl = (oauthUrl: URL | string | null | undefined) => {
|
|
|
99
115
|
}
|
|
100
116
|
|
|
101
117
|
type QuilttConnectorProps = {
|
|
102
|
-
testId?: string
|
|
103
118
|
connectorId: string
|
|
104
119
|
connectionId?: string
|
|
105
120
|
institution?: string
|
|
106
121
|
oauthRedirectUrl: string
|
|
122
|
+
testId?: string
|
|
107
123
|
} & ConnectorSDKCallbacks
|
|
108
124
|
|
|
109
125
|
const QuilttConnector = ({
|
|
110
|
-
testId,
|
|
111
126
|
connectorId,
|
|
112
127
|
connectionId,
|
|
113
128
|
institution,
|
|
@@ -118,6 +133,7 @@ const QuilttConnector = ({
|
|
|
118
133
|
onExitSuccess,
|
|
119
134
|
onExitAbort,
|
|
120
135
|
onExitError,
|
|
136
|
+
testId,
|
|
121
137
|
}: QuilttConnectorProps) => {
|
|
122
138
|
const webViewRef = useRef<WebView>(null)
|
|
123
139
|
const { session } = useQuilttSession()
|
|
@@ -296,7 +312,11 @@ const QuilttConnector = ({
|
|
|
296
312
|
handleQuilttEvent(url)
|
|
297
313
|
return false
|
|
298
314
|
}
|
|
299
|
-
|
|
315
|
+
|
|
316
|
+
if (shouldRender(url)) {
|
|
317
|
+
return true
|
|
318
|
+
}
|
|
319
|
+
|
|
300
320
|
// Plaid set oauth url by doing window.location.href = url
|
|
301
321
|
// So we use `handleOAuthUrl` as a catch all and assume all url got to this step is Plaid OAuth url
|
|
302
322
|
handleOAuthUrl(url)
|
|
@@ -305,7 +325,10 @@ const QuilttConnector = ({
|
|
|
305
325
|
[handleQuilttEvent, isQuilttEvent, shouldRender]
|
|
306
326
|
)
|
|
307
327
|
|
|
308
|
-
if (!preFlightCheck.checked)
|
|
328
|
+
if (!preFlightCheck.checked) {
|
|
329
|
+
return <LoadingScreen testId="loading-screen" />
|
|
330
|
+
}
|
|
331
|
+
|
|
309
332
|
if (preFlightCheck.error) {
|
|
310
333
|
return (
|
|
311
334
|
<ErrorScreen
|
|
@@ -319,10 +342,8 @@ const QuilttConnector = ({
|
|
|
319
342
|
return (
|
|
320
343
|
<AndroidSafeAreaView testId={testId}>
|
|
321
344
|
<WebView
|
|
322
|
-
testID="webview"
|
|
323
345
|
ref={webViewRef}
|
|
324
346
|
// Plaid keeps sending window.location = 'about:srcdoc' and causes some noise in RN
|
|
325
|
-
// All whitelists are now handled in requestHandler, handleQuilttEvent and handleOAuthUrl
|
|
326
347
|
style={styles.webview}
|
|
327
348
|
originWhitelist={['*']}
|
|
328
349
|
source={{ uri: connectorUrl }}
|
|
@@ -337,6 +358,7 @@ const QuilttConnector = ({
|
|
|
337
358
|
contentInsetAdjustmentBehavior="never" // Controls how the WebView adjusts its content layout relative to safe areas and system UI
|
|
338
359
|
showsVerticalScrollIndicator={false}
|
|
339
360
|
showsHorizontalScrollIndicator={false}
|
|
361
|
+
testID="webview"
|
|
340
362
|
{...(Platform.OS === 'ios'
|
|
341
363
|
? {
|
|
342
364
|
decelerationRate: 'normal',
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export const getErrorMessage = (responseStatus?: number, error?: Error): string => {
|
|
2
2
|
if (error)
|
|
3
|
-
return `An error occurred while checking the
|
|
3
|
+
return `An error occurred while checking the Connector URL: ${error?.name} \n${error?.message}`
|
|
4
4
|
return responseStatus
|
|
5
|
-
? `
|
|
6
|
-
: 'An error occurred while checking the
|
|
5
|
+
? `An error occurred loading the Connector. Response status: ${responseStatus}`
|
|
6
|
+
: 'An error occurred while checking the Connector URL'
|
|
7
7
|
}
|