diff --git a/src/app.ts b/src/app.ts index 7de8212..792678e 100644 --- a/src/app.ts +++ b/src/app.ts @@ -39,6 +39,7 @@ export default class BaseApp { readonly P1_VALUES: P1_VALUESGeneric readonly REQUIRED_PATH_LENGTHS?: number[] readonly CHUNK_SIZE: number + readonly CUSTOM_APP_ERROR_DESCRIPTION?: Readonly> /** * Constructs a new BaseApp instance. @@ -56,6 +57,7 @@ export default class BaseApp { this.P1_VALUES = params.p1Values this.CHUNK_SIZE = params.chunkSize this.REQUIRED_PATH_LENGTHS = params.acceptedPathLengths + this.CUSTOM_APP_ERROR_DESCRIPTION = params.customAppErrorDescription } /** @@ -125,7 +127,7 @@ export default class BaseApp { const statusList = [LedgerError.NoErrors, LedgerError.DataIsInvalid, LedgerError.BadKeyHandle] const responseBuffer = await this.transport.send(this.CLA, ins, payloadType, p2, chunk, statusList) - const response = processResponse(responseBuffer) + const response = processResponse(responseBuffer, this.CUSTOM_APP_ERROR_DESCRIPTION) return response } @@ -154,7 +156,7 @@ export default class BaseApp { async getVersion(): Promise { try { const responseBuffer = await this.transport.send(this.CLA, this.INS.GET_VERSION, 0, 0) - const response = processResponse(responseBuffer) + const response = processResponse(responseBuffer, this.CUSTOM_APP_ERROR_DESCRIPTION) // valid options are // test mode: 1 byte @@ -224,7 +226,7 @@ export default class BaseApp { async appInfo(): Promise { try { const responseBuffer = await this.transport.send(LEDGER_DASHBOARD_CLA, 0x01, 0, 0) - const response = processResponse(responseBuffer) + const response = processResponse(responseBuffer, this.CUSTOM_APP_ERROR_DESCRIPTION) const formatId = response.readBytes(1).readUInt8() @@ -264,7 +266,7 @@ export default class BaseApp { async deviceInfo(): Promise { try { const responseBuffer = await this.transport.send(0xe0, 0x01, 0, 0, Buffer.from([]), [LedgerError.NoErrors, 0x6e00]) - const response = processResponse(responseBuffer) + const response = processResponse(responseBuffer, this.CUSTOM_APP_ERROR_DESCRIPTION) const targetId = response.readBytes(4).toString('hex') diff --git a/src/common.ts b/src/common.ts index 2a030df..5d6218d 100644 --- a/src/common.ts +++ b/src/common.ts @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. *****************************************************************************/ -import { LedgerError } from './consts' +import { LedgerCustomError, LedgerError } from './consts' import { errorCodeToString } from './errors' import { ResponsePayload } from './payload' import { ResponseError } from './responseError' @@ -35,10 +35,11 @@ function isDict(v: any): boolean { * the payload is returned directly. Otherwise, an error object is thrown. * * @param responseRaw - The raw response buffer from the device, potentially containing error codes or data. + * @param customErrorList - Custom error description list to convert error code with. * @returns The payload as a buffer if no errors are found. * @throws {ResponseError} An object detailing the error if any is found. */ -export function processResponse(responseRaw: Buffer): ResponsePayload { +export function processResponse(responseRaw: Buffer, customErrorList?: Record): ResponsePayload { // Ensure the buffer is large enough to contain a return code if (responseRaw.length < 2) { throw ResponseError.fromReturnCode(LedgerError.EmptyBuffer) @@ -46,7 +47,7 @@ export function processResponse(responseRaw: Buffer): ResponsePayload { // Determine the return code from the last two bytes of the response const returnCode = responseRaw.readUInt16BE(responseRaw.length - 2) - let errorMessage = errorCodeToString(returnCode) + let errorMessage = errorCodeToString(returnCode, customErrorList) // Isolate the payload (all bytes except the last two) const payload = responseRaw.subarray(0, responseRaw.length - 2) @@ -70,12 +71,13 @@ export function processResponse(responseRaw: Buffer): ResponsePayload { * This function is deprecated and should not be used in new implementations. * * @param response - The raw response object that may contain error details. + * @param customErrorList - Custom error description list to convert error code with. * @returns A standardized error response object. */ -export function processErrorResponse(response: any): ResponseError { +export function processErrorResponse(response: any, customErrorList?: Record): ResponseError { if (isDict(response)) { if (Object.prototype.hasOwnProperty.call(response, 'statusCode')) { - return ResponseError.fromReturnCode(response.statusCode) + return ResponseError.fromReturnCode(response.statusCode, customErrorList) } if (Object.prototype.hasOwnProperty.call(response, 'returnCode') && Object.prototype.hasOwnProperty.call(response, 'errorMessage')) { diff --git a/src/responseError.ts b/src/responseError.ts index 8c0819d..fdd2e40 100644 --- a/src/responseError.ts +++ b/src/responseError.ts @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. *****************************************************************************/ +import { LedgerCustomError } from './consts' import { errorCodeToString } from './errors' /** @@ -37,9 +38,10 @@ export class ResponseError extends Error { /** * Creates a ResponseError instance from a return code. * @param returnCode - The return code to convert into a ResponseError. + * @param customErrorList - Custom error description list to convert error code with. * @returns A new instance of ResponseError. */ - static fromReturnCode(returnCode: number): ResponseError { - return new ResponseError(returnCode, errorCodeToString(returnCode)) + static fromReturnCode(returnCode: number, customErrorList?: Record): ResponseError { + return new ResponseError(returnCode, errorCodeToString(returnCode, customErrorList)) } } diff --git a/src/types.ts b/src/types.ts index 4a8dc42..64f7054 100644 --- a/src/types.ts +++ b/src/types.ts @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. *****************************************************************************/ +import { LedgerCustomError } from './consts' /** * Represents the version response from a device. @@ -76,6 +77,7 @@ export interface ConstructorParams { p1Values: P1_VALUESGeneric chunkSize: number acceptedPathLengths?: number[] + customAppErrorDescription?: Readonly> } export type BIP32Path = string