Skip to content

Commit

Permalink
fix(transport): propagate error message instead of returning unexpect…
Browse files Browse the repository at this point in the history
…ed error
  • Loading branch information
mroz22 committed Nov 25, 2024
1 parent cba164c commit 580a6d2
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 32 deletions.
7 changes: 6 additions & 1 deletion packages/connect/src/device/DeviceCommands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,12 @@ export class DeviceCommands {

this.callPromise = undefined;
if (!res.success) {
logger.warn('Received error', res.error);
logger.warn(
'Received error',
res.error,
// res.message is not propagated to higher levels, only logged here. webusb/node-bridge may return message with additional information
res.message,
);
throw new Error(res.error);
}

Expand Down
25 changes: 18 additions & 7 deletions packages/transport-bridge/src/http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { Descriptor, PathPublic, Session } from '@trezor/transport/src/types';
import { validateProtocolMessage } from '@trezor/transport/src/utils/bridgeProtocolMessage';
import { Log, arrayPartition, Throttler } from '@trezor/utils';
import { AbstractApi } from '@trezor/transport/src/api/abstract';
import { UNEXPECTED_ERROR } from '@trezor/transport/src/errors';

import { createCore } from './core';

Expand Down Expand Up @@ -78,7 +79,7 @@ const validateProtocolMessageBody =
return next({ ...request, body }, response);
} catch (error) {
response.statusCode = 400;
response.end(str({ error: error.message }));
response.end(str({ error: UNEXPECTED_ERROR, message: error.message }));
}
};

Expand Down Expand Up @@ -250,7 +251,7 @@ export class TrezordNode {
if (!result.success) {
res.statusCode = 400;

return res.end(str({ error: result.error }));
return res.end(str({ error: result.error, message: result.message }));
}
res.end(str(result.payload.descriptors));
});
Expand Down Expand Up @@ -289,7 +290,9 @@ export class TrezordNode {
if (!result.success) {
res.statusCode = 400;

return res.end(str({ error: result.error }));
return res.end(
str({ error: result.error, message: result.message }),
);
}
res.end(str({ session: result.payload.session }));
});
Expand All @@ -308,7 +311,9 @@ export class TrezordNode {
if (!result.success) {
res.statusCode = 400;

return res.end(str({ error: result.error }));
return res.end(
str({ error: result.error, message: result.message }),
);
}
res.end(str({ session: req.params.session }));
});
Expand All @@ -331,7 +336,9 @@ export class TrezordNode {
if (!result.success) {
res.statusCode = 400;

return res.end(str({ error: result.error }));
return res.end(
str({ error: result.error, message: result.message }),
);
}
res.end(str(result.payload));
});
Expand All @@ -354,7 +361,9 @@ export class TrezordNode {
if (!result.success) {
res.statusCode = 400;

return res.end(str({ error: result.error }));
return res.end(
str({ error: result.error, message: result.message }),
);
}
res.end(str(result.payload));
});
Expand All @@ -377,7 +386,9 @@ export class TrezordNode {
if (!result.success) {
res.statusCode = 400;

return res.end(str({ error: result.error }));
return res.end(
str({ error: result.error, message: result.message }),
);
}
res.end(str(result.payload));
});
Expand Down
1 change: 1 addition & 0 deletions packages/transport-bridge/tests/http.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,7 @@ describe('http', () => {
});
expect(res).toMatchObject({
success: false,
error: 'unexpected error',
message: 'Invalid BridgeProtocolMessage protocol',
});

Expand Down
5 changes: 1 addition & 4 deletions packages/transport/src/api/usb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -219,10 +219,7 @@ export class UsbApi extends AbstractApi {
return this.error({ error: ERRORS.DEVICE_DISCONNECTED_DURING_ACTION });
}

return this.unknownError(err, [
ERRORS.ABORTED_BY_SIGNAL,
ERRORS.INTERFACE_DATA_TRANSFER,
]);
return this.error({ error: ERRORS.INTERFACE_DATA_TRANSFER, message: err.message });
}
}

Expand Down
13 changes: 4 additions & 9 deletions packages/transport/src/transports/bridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ export class BridgeTransport extends AbstractTransport {

if (!response.success) {
if (response.error === ERRORS.UNEXPECTED_ERROR) {
return response;
return this.unknownError(response.error);
}
if (response.error === ERRORS.HTTP_ERROR) {
return this.error({ error: response.error });
Expand All @@ -380,24 +380,19 @@ export class BridgeTransport extends AbstractTransport {
ERRORS.INTERFACE_UNABLE_TO_OPEN_DEVICE,
ERRORS.DEVICE_DISCONNECTED_DURING_ACTION,
]);
case '/read':
case '/call':
case '/read':
case '/post':
return this.unknownError(response.error, [
ERRORS.SESSION_NOT_FOUND,
ERRORS.DEVICE_DISCONNECTED_DURING_ACTION,
ERRORS.OTHER_CALL_IN_PROGRESS,
ERRORS.INTERFACE_DATA_TRANSFER,
PROTOCOL_MALFORMED,
]);
case '/enumerate':
case '/listen':
return this.unknownError(response.error);
case '/post':
return this.unknownError(response.error, [
ERRORS.SESSION_NOT_FOUND,
ERRORS.DEVICE_DISCONNECTED_DURING_ACTION,
ERRORS.OTHER_CALL_IN_PROGRESS,
PROTOCOL_MALFORMED,
]);
case '/release':
return this.unknownError(response.error, [
ERRORS.SESSION_NOT_FOUND,
Expand Down
15 changes: 5 additions & 10 deletions packages/transport/src/types/apiCall.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,11 @@ export interface Success<T> {
payload: T;
}

export type ErrorGeneric<ErrorType> = ErrorType extends AnyError
? {
success: false;
error: ErrorType;
}
: {
success: false;
error: ErrorType;
message?: string;
};
export type ErrorGeneric<ErrorType> = {
success: false;
error: ErrorType;
message?: string;
};

export type ResultWithTypedError<T, E> = Success<T> | ErrorGeneric<E>;
export type AsyncResultWithTypedError<T, E> = Promise<Success<T> | ErrorGeneric<E>>;
Expand Down
15 changes: 15 additions & 0 deletions packages/transport/src/utils/bridgeApiCall.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ export async function bridgeApiCall(options: HttpRequestOptions) {

// if status is not 200. response should be interpreted as error.
if (!res.ok) {
// this block only changes error messages from old bridge to the same messages returned by new bridge / connect usb stack
const errStr =
typeof resParsed !== 'string' && 'error' in resParsed
? (resParsed.error as string)
Expand All @@ -97,6 +98,20 @@ export async function bridgeApiCall(options: HttpRequestOptions) {
return error({ error: PROTOCOL_MALFORMED });
}

if (
typeof resParsed !== 'string' &&
'error' in resParsed &&
typeof resParsed.error === 'string'
) {
return error({
error: resParsed.error,
message:
'message' in resParsed && typeof resParsed.message === 'string'
? resParsed.message
: undefined,
});
}

return unknownError(new Error(errStr), Object.values(ERRORS));
}

Expand Down
2 changes: 1 addition & 1 deletion packages/transport/tests/apiUsb.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ describe('api/usb', () => {

const result = await promise;
if (result.success) throw new Error('Unexpected success');
expect(result.error).toContain('Aborted by signal');
expect(result.error).toContain('A transfer error has occurred.');
expect(reset).toHaveBeenCalledTimes(1);
});

Expand Down

0 comments on commit 580a6d2

Please sign in to comment.