@onekeyfe/hd-transport-web-device 1.2.3-alpha.5 → 1.2.3-alpha.7
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.
|
@@ -64,54 +64,6 @@ describe('WebUsbTransport protocol probe cache', () => {
|
|
|
64
64
|
}
|
|
65
65
|
);
|
|
66
66
|
|
|
67
|
-
test('reports claimInterface failures as WebUSB device access errors', async () => {
|
|
68
|
-
const webusb = new WebUsbTransport();
|
|
69
|
-
const path = 'connected-usb-device';
|
|
70
|
-
const claimError = Object.assign(new Error('Unable to claim interface'), {
|
|
71
|
-
name: 'NetworkError',
|
|
72
|
-
});
|
|
73
|
-
const device = {
|
|
74
|
-
opened: true,
|
|
75
|
-
configuration: { configurationValue: 1 },
|
|
76
|
-
configurations: [],
|
|
77
|
-
claimInterface: jest.fn().mockRejectedValue(claimError),
|
|
78
|
-
};
|
|
79
|
-
jest.spyOn(webusb, 'findDevice').mockResolvedValue(device as unknown as USBDevice);
|
|
80
|
-
jest.spyOn(webusb, 'getConnectedDevices').mockResolvedValue([]);
|
|
81
|
-
const state = webusb as unknown as { deviceProtocol: Map<string, 'V1' | 'V2'> };
|
|
82
|
-
state.deviceProtocol.set(path, 'V1');
|
|
83
|
-
|
|
84
|
-
await expect(webusb.connectToDevice(path, false)).rejects.toMatchObject({
|
|
85
|
-
errorCode: HardwareErrorCode.WebUsbDeviceAccessError,
|
|
86
|
-
params: {
|
|
87
|
-
operation: 'claimInterface',
|
|
88
|
-
nativeErrorName: 'NetworkError',
|
|
89
|
-
nativeErrorMessage: 'Unable to claim interface',
|
|
90
|
-
},
|
|
91
|
-
});
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
test('reports transferIn failures as WebUSB device access errors', async () => {
|
|
95
|
-
const webusb = new WebUsbTransport() as any;
|
|
96
|
-
const path = 'connected-usb-device';
|
|
97
|
-
const transferError = Object.assign(new Error('Transfer endpoint is unavailable'), {
|
|
98
|
-
name: 'NetworkError',
|
|
99
|
-
});
|
|
100
|
-
webusb.findDevice = jest.fn().mockResolvedValue({
|
|
101
|
-
opened: true,
|
|
102
|
-
transferIn: jest.fn().mockRejectedValue(transferError),
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
await expect(webusb.transferInWithRetry(path, 64)).rejects.toMatchObject({
|
|
106
|
-
errorCode: HardwareErrorCode.WebUsbDeviceAccessError,
|
|
107
|
-
params: {
|
|
108
|
-
operation: 'transferIn',
|
|
109
|
-
nativeErrorName: 'NetworkError',
|
|
110
|
-
nativeErrorMessage: 'Transfer endpoint is unavailable',
|
|
111
|
-
},
|
|
112
|
-
});
|
|
113
|
-
});
|
|
114
|
-
|
|
115
67
|
test('acquire skips the wire probe when the protocol is already cached', async () => {
|
|
116
68
|
const webusb = buildAcquirableTransport();
|
|
117
69
|
const path = 'pro-webusb';
|
|
@@ -238,15 +238,9 @@ describe('WebUsbTransport Protocol V2 timeout recovery', () => {
|
|
|
238
238
|
webusb.resetConnectionAfterProbe = jest.fn();
|
|
239
239
|
await webusb.rotateProtocolV2UsbGeneration(path, 'test connection');
|
|
240
240
|
|
|
241
|
-
await expect(
|
|
242
|
-
|
|
243
|
-
)
|
|
244
|
-
errorCode: HardwareErrorCode.BridgeDeviceDisconnected,
|
|
245
|
-
params: {
|
|
246
|
-
operation: 'transferIn',
|
|
247
|
-
nativeErrorMessage: 'NetworkError: transferIn device disconnected',
|
|
248
|
-
},
|
|
249
|
-
});
|
|
241
|
+
await expect(webusb.callProtocolV2(path, 'Ping', { message: 'read-error' })).rejects.toThrow(
|
|
242
|
+
'NetworkError'
|
|
243
|
+
);
|
|
250
244
|
|
|
251
245
|
expect(webusb.readProtocolV2UsbPacket).toHaveBeenCalledTimes(1);
|
|
252
246
|
expect(webusb.resetProtocolV2UsbNativeLink).toHaveBeenCalledWith(
|
package/dist/index.d.ts
CHANGED
|
@@ -118,7 +118,7 @@ declare class WebUsbTransport extends ProtocolV2UsbTransportBase<string> {
|
|
|
118
118
|
/**
|
|
119
119
|
* Connect to device with retry mechanism
|
|
120
120
|
*/
|
|
121
|
-
connect(path: string, first: boolean): Promise<
|
|
121
|
+
connect(path: string, first: boolean): Promise<void>;
|
|
122
122
|
/**
|
|
123
123
|
* Discover vendor-class (0xFF) interface and its IN/OUT endpoint numbers from USB descriptors.
|
|
124
124
|
* Falls back to legacy hardcoded values if no vendor interface is found.
|
|
@@ -128,7 +128,7 @@ declare class WebUsbTransport extends ProtocolV2UsbTransportBase<string> {
|
|
|
128
128
|
* Connect to specific device.
|
|
129
129
|
* Discovers interface/endpoint numbers from USB descriptors on first connection.
|
|
130
130
|
*/
|
|
131
|
-
connectToDevice(path: string, first: boolean): Promise<
|
|
131
|
+
connectToDevice(path: string, first: boolean): Promise<void>;
|
|
132
132
|
private closeOpenDevice;
|
|
133
133
|
private clearEndpointHalt;
|
|
134
134
|
/**
|
|
@@ -141,10 +141,6 @@ declare class WebUsbTransport extends ProtocolV2UsbTransportBase<string> {
|
|
|
141
141
|
private assertAcquired;
|
|
142
142
|
post(session: string, name: string, data: Record<string, unknown>): Promise<void>;
|
|
143
143
|
private getErrorMessage;
|
|
144
|
-
private getErrorName;
|
|
145
|
-
private isWebUsbIoHardwareError;
|
|
146
|
-
private isDeviceStillEnumerated;
|
|
147
|
-
private throwWebUsbIoError;
|
|
148
144
|
private isRetryablePacketIoError;
|
|
149
145
|
private reconnectForPacketIoRetry;
|
|
150
146
|
private getTransferInData;
|
package/dist/index.js
CHANGED
|
@@ -395,12 +395,7 @@ class WebUsbTransport extends transport.ProtocolV2UsbTransportBase {
|
|
|
395
395
|
}
|
|
396
396
|
const endpoints = this.discoverEndpoints(device);
|
|
397
397
|
this.deviceEndpoints.set(path, endpoints);
|
|
398
|
-
|
|
399
|
-
yield device.claimInterface(endpoints.interfaceNumber);
|
|
400
|
-
}
|
|
401
|
-
catch (error) {
|
|
402
|
-
return this.throwWebUsbIoError(path, 'claimInterface', error);
|
|
403
|
-
}
|
|
398
|
+
yield device.claimInterface(endpoints.interfaceNumber);
|
|
404
399
|
yield this.clearEndpointHalt(device, 'in', endpoints.endpointIn);
|
|
405
400
|
yield this.clearEndpointHalt(device, 'out', endpoints.endpointOut);
|
|
406
401
|
});
|
|
@@ -464,59 +459,6 @@ class WebUsbTransport extends transport.ProtocolV2UsbTransportBase {
|
|
|
464
459
|
}
|
|
465
460
|
return String(error);
|
|
466
461
|
}
|
|
467
|
-
getErrorName(error) {
|
|
468
|
-
if (typeof error === 'object' && error && 'name' in error) {
|
|
469
|
-
const { name } = error;
|
|
470
|
-
return typeof name === 'string' ? name : String(name !== null && name !== void 0 ? name : '');
|
|
471
|
-
}
|
|
472
|
-
return '';
|
|
473
|
-
}
|
|
474
|
-
isWebUsbIoHardwareError(error) {
|
|
475
|
-
return (error instanceof hdShared.HardwareError &&
|
|
476
|
-
(error.errorCode === hdShared.HardwareErrorCode.BridgeDeviceDisconnected ||
|
|
477
|
-
error.errorCode === hdShared.HardwareErrorCode.WebUsbDeviceAccessError));
|
|
478
|
-
}
|
|
479
|
-
isDeviceStillEnumerated(path) {
|
|
480
|
-
var _a;
|
|
481
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
482
|
-
if (!this.usb)
|
|
483
|
-
return undefined;
|
|
484
|
-
try {
|
|
485
|
-
const devices = yield this.usb.getDevices();
|
|
486
|
-
return devices.some(device => hdShared.resolveOneKeyUsbDevicePath(device) === path);
|
|
487
|
-
}
|
|
488
|
-
catch (error) {
|
|
489
|
-
(_a = this.Log) === null || _a === void 0 ? void 0 : _a.debug('[WebUsbTransport] failed to verify WebUSB device presence:', error);
|
|
490
|
-
return undefined;
|
|
491
|
-
}
|
|
492
|
-
});
|
|
493
|
-
}
|
|
494
|
-
throwWebUsbIoError(path, operation, error) {
|
|
495
|
-
var _a;
|
|
496
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
497
|
-
if (this.isWebUsbIoHardwareError(error))
|
|
498
|
-
throw error;
|
|
499
|
-
if (error instanceof transport.ProtocolV2LinkError && error.code !== 'io')
|
|
500
|
-
throw error;
|
|
501
|
-
const nativeError = error instanceof transport.ProtocolV2LinkError ? (_a = error.cause) !== null && _a !== void 0 ? _a : error : error;
|
|
502
|
-
if (this.isWebUsbIoHardwareError(nativeError))
|
|
503
|
-
throw nativeError;
|
|
504
|
-
const nativeErrorName = this.getErrorName(nativeError);
|
|
505
|
-
const nativeErrorMessage = this.getErrorMessage(nativeError);
|
|
506
|
-
const disconnectedByMessage = /(?:device )?disconnected|device not found|action was interrupted/i.test(`${nativeErrorName}: ${nativeErrorMessage}`);
|
|
507
|
-
const stillEnumerated = disconnectedByMessage
|
|
508
|
-
? false
|
|
509
|
-
: yield this.isDeviceStillEnumerated(path);
|
|
510
|
-
const errorCode = disconnectedByMessage || stillEnumerated === false
|
|
511
|
-
? hdShared.HardwareErrorCode.BridgeDeviceDisconnected
|
|
512
|
-
: hdShared.HardwareErrorCode.WebUsbDeviceAccessError;
|
|
513
|
-
throw hdShared.ERRORS.TypedError(errorCode, nativeErrorMessage || undefined, {
|
|
514
|
-
operation,
|
|
515
|
-
nativeErrorName: nativeErrorName || undefined,
|
|
516
|
-
nativeErrorMessage: nativeErrorMessage || undefined,
|
|
517
|
-
});
|
|
518
|
-
});
|
|
519
|
-
}
|
|
520
462
|
isRetryablePacketIoError(error) {
|
|
521
463
|
const message = this.getErrorMessage(error).toLowerCase();
|
|
522
464
|
return (message.includes('transferout') ||
|
|
@@ -583,7 +525,7 @@ class WebUsbTransport extends transport.ProtocolV2UsbTransportBase {
|
|
|
583
525
|
lastError = error;
|
|
584
526
|
const shouldRetry = attempt < PACKET_IO_MAX_RETRIES && this.isRetryablePacketIoError(error);
|
|
585
527
|
if (!shouldRetry) {
|
|
586
|
-
|
|
528
|
+
throw error;
|
|
587
529
|
}
|
|
588
530
|
try {
|
|
589
531
|
yield this.reconnectForPacketIoRetry(path, 'out', attempt, error);
|
|
@@ -594,7 +536,7 @@ class WebUsbTransport extends transport.ProtocolV2UsbTransportBase {
|
|
|
594
536
|
}
|
|
595
537
|
}
|
|
596
538
|
}
|
|
597
|
-
|
|
539
|
+
throw lastError;
|
|
598
540
|
});
|
|
599
541
|
}
|
|
600
542
|
transferOutOnce(path, packet) {
|
|
@@ -635,7 +577,7 @@ class WebUsbTransport extends transport.ProtocolV2UsbTransportBase {
|
|
|
635
577
|
}
|
|
636
578
|
const shouldRetry = attempt < PACKET_IO_MAX_RETRIES && this.isRetryablePacketIoError(error);
|
|
637
579
|
if (!shouldRetry) {
|
|
638
|
-
|
|
580
|
+
throw error;
|
|
639
581
|
}
|
|
640
582
|
try {
|
|
641
583
|
yield this.reconnectForPacketIoRetry(path, 'in', attempt, error);
|
|
@@ -646,7 +588,7 @@ class WebUsbTransport extends transport.ProtocolV2UsbTransportBase {
|
|
|
646
588
|
}
|
|
647
589
|
}
|
|
648
590
|
}
|
|
649
|
-
|
|
591
|
+
throw lastError;
|
|
650
592
|
});
|
|
651
593
|
}
|
|
652
594
|
transferInOnce(path, length) {
|
|
@@ -723,9 +665,7 @@ class WebUsbTransport extends transport.ProtocolV2UsbTransportBase {
|
|
|
723
665
|
});
|
|
724
666
|
return true;
|
|
725
667
|
}
|
|
726
|
-
catch (
|
|
727
|
-
if (this.isWebUsbIoHardwareError(error))
|
|
728
|
-
throw error;
|
|
668
|
+
catch (_error) {
|
|
729
669
|
return false;
|
|
730
670
|
}
|
|
731
671
|
});
|
|
@@ -740,7 +680,6 @@ class WebUsbTransport extends transport.ProtocolV2UsbTransportBase {
|
|
|
740
680
|
timeoutMs: PROTOCOL_V2_PROBE_TIMEOUT,
|
|
741
681
|
logger: this.Log,
|
|
742
682
|
logPrefix: 'ProtocolV2 WebUSB',
|
|
743
|
-
shouldRethrow: error => this.isWebUsbIoHardwareError(error),
|
|
744
683
|
});
|
|
745
684
|
});
|
|
746
685
|
}
|
|
@@ -787,15 +726,7 @@ class WebUsbTransport extends transport.ProtocolV2UsbTransportBase {
|
|
|
787
726
|
}
|
|
788
727
|
callProtocolV2(path, name, data, options) {
|
|
789
728
|
return __awaiter(this, void 0, void 0, function* () {
|
|
790
|
-
|
|
791
|
-
return yield this.callProtocolV2Usb(path, name, data, options);
|
|
792
|
-
}
|
|
793
|
-
catch (error) {
|
|
794
|
-
if (!(error instanceof transport.ProtocolV2LinkError) || error.code !== 'io')
|
|
795
|
-
throw error;
|
|
796
|
-
const operation = error.message.includes(' USB write failed:') ? 'transferOut' : 'transferIn';
|
|
797
|
-
return this.throwWebUsbIoError(path, operation, error);
|
|
798
|
-
}
|
|
729
|
+
return this.callProtocolV2Usb(path, name, data, options);
|
|
799
730
|
});
|
|
800
731
|
}
|
|
801
732
|
receiveData(path, timeoutMs) {
|
package/dist/webusb.d.ts
CHANGED
|
@@ -44,18 +44,14 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
|
|
|
44
44
|
private createProtocolDetectionError;
|
|
45
45
|
private detectProtocol;
|
|
46
46
|
findDevice(path: string): Promise<USBDevice>;
|
|
47
|
-
connect(path: string, first: boolean): Promise<
|
|
47
|
+
connect(path: string, first: boolean): Promise<void>;
|
|
48
48
|
private discoverEndpoints;
|
|
49
|
-
connectToDevice(path: string, first: boolean): Promise<
|
|
49
|
+
connectToDevice(path: string, first: boolean): Promise<void>;
|
|
50
50
|
private closeOpenDevice;
|
|
51
51
|
private clearEndpointHalt;
|
|
52
52
|
private assertAcquired;
|
|
53
53
|
post(session: string, name: string, data: Record<string, unknown>): Promise<void>;
|
|
54
54
|
private getErrorMessage;
|
|
55
|
-
private getErrorName;
|
|
56
|
-
private isWebUsbIoHardwareError;
|
|
57
|
-
private isDeviceStillEnumerated;
|
|
58
|
-
private throwWebUsbIoError;
|
|
59
55
|
private isRetryablePacketIoError;
|
|
60
56
|
private reconnectForPacketIoRetry;
|
|
61
57
|
private getTransferInData;
|
package/dist/webusb.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webusb.d.ts","sourceRoot":"","sources":["../src/webusb.ts"],"names":[],"mappings":";;AACA,OAAO,SAAS,EAAE,EAQhB,0BAA0B,EAG3B,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"webusb.d.ts","sourceRoot":"","sources":["../src/webusb.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onekeyfe/hd-transport-web-device",
|
|
3
|
-
"version": "1.2.3-alpha.
|
|
3
|
+
"version": "1.2.3-alpha.7",
|
|
4
4
|
"author": "OneKey",
|
|
5
5
|
"homepage": "https://github.com/OneKeyHQ/hardware-js-sdk#readme",
|
|
6
6
|
"license": "MIT",
|
|
@@ -21,13 +21,13 @@
|
|
|
21
21
|
"lint:fix": "eslint . --fix"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@onekeyfe/hd-shared": "1.2.3-alpha.
|
|
25
|
-
"@onekeyfe/hd-transport": "1.2.3-alpha.
|
|
24
|
+
"@onekeyfe/hd-shared": "1.2.3-alpha.7",
|
|
25
|
+
"@onekeyfe/hd-transport": "1.2.3-alpha.7"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
|
-
"@onekeyfe/hd-transport-electron": "1.2.3-alpha.
|
|
28
|
+
"@onekeyfe/hd-transport-electron": "1.2.3-alpha.7",
|
|
29
29
|
"@types/w3c-web-usb": "^1.0.6",
|
|
30
30
|
"@types/web-bluetooth": "^0.0.17"
|
|
31
31
|
},
|
|
32
|
-
"gitHead": "
|
|
32
|
+
"gitHead": "b71eb64f2fc6b58ec7847f93cc99225bfec04d5b"
|
|
33
33
|
}
|
package/src/webusb.ts
CHANGED
|
@@ -13,7 +13,6 @@ import transport, {
|
|
|
13
13
|
} from '@onekeyfe/hd-transport';
|
|
14
14
|
import {
|
|
15
15
|
ERRORS,
|
|
16
|
-
HardwareError,
|
|
17
16
|
HardwareErrorCode,
|
|
18
17
|
ONEKEY_WEBUSB_FILTER,
|
|
19
18
|
inferProtocolHintFromUsbId,
|
|
@@ -71,8 +70,6 @@ interface TransferCancelToken {
|
|
|
71
70
|
cancelled: boolean;
|
|
72
71
|
}
|
|
73
72
|
|
|
74
|
-
type WebUsbOperation = 'claimInterface' | 'transferIn' | 'transferOut';
|
|
75
|
-
|
|
76
73
|
/**
|
|
77
74
|
* The navigator.usb disconnect listener is module-scoped and attached at most
|
|
78
75
|
* once: listeners on navigator.usb are global and never garbage collected, so a
|
|
@@ -595,11 +592,7 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
|
|
|
595
592
|
// Discover endpoints from USB descriptors; descriptors are not used for protocol selection.
|
|
596
593
|
const endpoints = this.discoverEndpoints(device);
|
|
597
594
|
this.deviceEndpoints.set(path, endpoints);
|
|
598
|
-
|
|
599
|
-
await device.claimInterface(endpoints.interfaceNumber);
|
|
600
|
-
} catch (error) {
|
|
601
|
-
return this.throwWebUsbIoError(path, 'claimInterface', error);
|
|
602
|
-
}
|
|
595
|
+
await device.claimInterface(endpoints.interfaceNumber);
|
|
603
596
|
await this.clearEndpointHalt(device, 'in', endpoints.endpointIn);
|
|
604
597
|
await this.clearEndpointHalt(device, 'out', endpoints.endpointOut);
|
|
605
598
|
}
|
|
@@ -669,65 +662,6 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
|
|
|
669
662
|
return String(error);
|
|
670
663
|
}
|
|
671
664
|
|
|
672
|
-
private getErrorName(error: unknown) {
|
|
673
|
-
if (typeof error === 'object' && error && 'name' in error) {
|
|
674
|
-
const { name } = error as { name?: unknown };
|
|
675
|
-
return typeof name === 'string' ? name : String(name ?? '');
|
|
676
|
-
}
|
|
677
|
-
return '';
|
|
678
|
-
}
|
|
679
|
-
|
|
680
|
-
private isWebUsbIoHardwareError(error: unknown): error is HardwareError {
|
|
681
|
-
return (
|
|
682
|
-
error instanceof HardwareError &&
|
|
683
|
-
(error.errorCode === HardwareErrorCode.BridgeDeviceDisconnected ||
|
|
684
|
-
error.errorCode === HardwareErrorCode.WebUsbDeviceAccessError)
|
|
685
|
-
);
|
|
686
|
-
}
|
|
687
|
-
|
|
688
|
-
private async isDeviceStillEnumerated(path: string): Promise<boolean | undefined> {
|
|
689
|
-
if (!this.usb) return undefined;
|
|
690
|
-
try {
|
|
691
|
-
const devices = await this.usb.getDevices();
|
|
692
|
-
return devices.some(device => resolveOneKeyUsbDevicePath(device) === path);
|
|
693
|
-
} catch (error) {
|
|
694
|
-
this.Log?.debug('[WebUsbTransport] failed to verify WebUSB device presence:', error);
|
|
695
|
-
return undefined;
|
|
696
|
-
}
|
|
697
|
-
}
|
|
698
|
-
|
|
699
|
-
private async throwWebUsbIoError(
|
|
700
|
-
path: string,
|
|
701
|
-
operation: WebUsbOperation,
|
|
702
|
-
error: unknown
|
|
703
|
-
): Promise<never> {
|
|
704
|
-
if (this.isWebUsbIoHardwareError(error)) throw error;
|
|
705
|
-
if (error instanceof ProtocolV2LinkError && error.code !== 'io') throw error;
|
|
706
|
-
|
|
707
|
-
const nativeError = error instanceof ProtocolV2LinkError ? error.cause ?? error : error;
|
|
708
|
-
if (this.isWebUsbIoHardwareError(nativeError)) throw nativeError;
|
|
709
|
-
|
|
710
|
-
const nativeErrorName = this.getErrorName(nativeError);
|
|
711
|
-
const nativeErrorMessage = this.getErrorMessage(nativeError);
|
|
712
|
-
const disconnectedByMessage =
|
|
713
|
-
/(?:device )?disconnected|device not found|action was interrupted/i.test(
|
|
714
|
-
`${nativeErrorName}: ${nativeErrorMessage}`
|
|
715
|
-
);
|
|
716
|
-
const stillEnumerated = disconnectedByMessage
|
|
717
|
-
? false
|
|
718
|
-
: await this.isDeviceStillEnumerated(path);
|
|
719
|
-
const errorCode =
|
|
720
|
-
disconnectedByMessage || stillEnumerated === false
|
|
721
|
-
? HardwareErrorCode.BridgeDeviceDisconnected
|
|
722
|
-
: HardwareErrorCode.WebUsbDeviceAccessError;
|
|
723
|
-
|
|
724
|
-
throw ERRORS.TypedError(errorCode, nativeErrorMessage || undefined, {
|
|
725
|
-
operation,
|
|
726
|
-
nativeErrorName: nativeErrorName || undefined,
|
|
727
|
-
nativeErrorMessage: nativeErrorMessage || undefined,
|
|
728
|
-
});
|
|
729
|
-
}
|
|
730
|
-
|
|
731
665
|
private isRetryablePacketIoError(error: unknown) {
|
|
732
666
|
const message = this.getErrorMessage(error).toLowerCase();
|
|
733
667
|
return (
|
|
@@ -808,7 +742,7 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
|
|
|
808
742
|
lastError = error;
|
|
809
743
|
const shouldRetry = attempt < PACKET_IO_MAX_RETRIES && this.isRetryablePacketIoError(error);
|
|
810
744
|
if (!shouldRetry) {
|
|
811
|
-
|
|
745
|
+
throw error;
|
|
812
746
|
}
|
|
813
747
|
try {
|
|
814
748
|
await this.reconnectForPacketIoRetry(path, 'out', attempt, error);
|
|
@@ -822,7 +756,7 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
|
|
|
822
756
|
}
|
|
823
757
|
}
|
|
824
758
|
}
|
|
825
|
-
|
|
759
|
+
throw lastError;
|
|
826
760
|
}
|
|
827
761
|
|
|
828
762
|
private async transferOutOnce(path: string, packet: Uint8Array) {
|
|
@@ -864,7 +798,7 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
|
|
|
864
798
|
}
|
|
865
799
|
const shouldRetry = attempt < PACKET_IO_MAX_RETRIES && this.isRetryablePacketIoError(error);
|
|
866
800
|
if (!shouldRetry) {
|
|
867
|
-
|
|
801
|
+
throw error;
|
|
868
802
|
}
|
|
869
803
|
try {
|
|
870
804
|
await this.reconnectForPacketIoRetry(path, 'in', attempt, error);
|
|
@@ -878,7 +812,7 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
|
|
|
878
812
|
}
|
|
879
813
|
}
|
|
880
814
|
}
|
|
881
|
-
|
|
815
|
+
throw lastError;
|
|
882
816
|
}
|
|
883
817
|
|
|
884
818
|
private async transferInOnce(path: string, length: number): Promise<DataView> {
|
|
@@ -960,8 +894,7 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
|
|
|
960
894
|
}
|
|
961
895
|
);
|
|
962
896
|
return true;
|
|
963
|
-
} catch (
|
|
964
|
-
if (this.isWebUsbIoHardwareError(error)) throw error;
|
|
897
|
+
} catch (_error) {
|
|
965
898
|
return false;
|
|
966
899
|
}
|
|
967
900
|
}
|
|
@@ -976,7 +909,6 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
|
|
|
976
909
|
timeoutMs: PROTOCOL_V2_PROBE_TIMEOUT,
|
|
977
910
|
logger: this.Log,
|
|
978
911
|
logPrefix: 'ProtocolV2 WebUSB',
|
|
979
|
-
shouldRethrow: error => this.isWebUsbIoHardwareError(error),
|
|
980
912
|
});
|
|
981
913
|
}
|
|
982
914
|
|
|
@@ -1054,13 +986,7 @@ export default class WebUsbTransport extends ProtocolV2UsbTransportBase<string>
|
|
|
1054
986
|
data: Record<string, unknown>,
|
|
1055
987
|
options?: TransportCallOptions
|
|
1056
988
|
) {
|
|
1057
|
-
|
|
1058
|
-
return await this.callProtocolV2Usb(path, name, data, options);
|
|
1059
|
-
} catch (error) {
|
|
1060
|
-
if (!(error instanceof ProtocolV2LinkError) || error.code !== 'io') throw error;
|
|
1061
|
-
const operation = error.message.includes(' USB write failed:') ? 'transferOut' : 'transferIn';
|
|
1062
|
-
return this.throwWebUsbIoError(path, operation, error);
|
|
1063
|
-
}
|
|
989
|
+
return this.callProtocolV2Usb(path, name, data, options);
|
|
1064
990
|
}
|
|
1065
991
|
|
|
1066
992
|
/**
|