From eeea3e62a01638b37c8bb8d6f8fdeac129a4afae Mon Sep 17 00:00:00 2001 From: Sebastian Date: Tue, 17 Jan 2023 15:58:20 -0300 Subject: stronger type check to be sure that ErrorDetails is consistent --- packages/taler-wallet-core/src/errors.ts | 66 ++++++++++++++++------ .../src/operations/backup/index.ts | 2 +- packages/taler-wallet-core/src/util/http.ts | 14 ++++- .../src/browserHttpLib.ts | 12 ++-- .../src/serviceWorkerHttpLib.ts | 19 +++++-- 5 files changed, 84 insertions(+), 29 deletions(-) diff --git a/packages/taler-wallet-core/src/errors.ts b/packages/taler-wallet-core/src/errors.ts index 7dbba2e2e..038bdbc7c 100644 --- a/packages/taler-wallet-core/src/errors.ts +++ b/packages/taler-wallet-core/src/errors.ts @@ -32,6 +32,8 @@ import { TransactionType, } from "@gnu-taler/taler-util"; +type empty = Record; + export interface DetailsMap { [TalerErrorCode.WALLET_PENDING_OPERATION_FAILED]: { innerError: TalerErrorDetail; @@ -44,13 +46,13 @@ export interface DetailsMap { exchangeProtocolVersion: string; walletProtocolVersion: string; }; - [TalerErrorCode.WALLET_WITHDRAWAL_OPERATION_ABORTED_BY_BANK]: {}; - [TalerErrorCode.WALLET_TIPPING_COIN_SIGNATURE_INVALID]: {}; + [TalerErrorCode.WALLET_WITHDRAWAL_OPERATION_ABORTED_BY_BANK]: empty; + [TalerErrorCode.WALLET_TIPPING_COIN_SIGNATURE_INVALID]: empty; [TalerErrorCode.WALLET_ORDER_ALREADY_CLAIMED]: { orderId: string; claimUrl: string; }; - [TalerErrorCode.WALLET_CONTRACT_TERMS_MALFORMED]: {}; + [TalerErrorCode.WALLET_CONTRACT_TERMS_MALFORMED]: empty; [TalerErrorCode.WALLET_CONTRACT_TERMS_SIGNATURE_INVALID]: { merchantPub: string; orderId: string; @@ -62,18 +64,46 @@ export interface DetailsMap { [TalerErrorCode.WALLET_INVALID_TALER_PAY_URI]: { talerPayUri: string; }; - [TalerErrorCode.WALLET_UNEXPECTED_REQUEST_ERROR]: {}; - [TalerErrorCode.WALLET_UNEXPECTED_EXCEPTION]: {}; - [TalerErrorCode.WALLET_BANK_INTEGRATION_PROTOCOL_VERSION_INCOMPATIBLE]: {}; - [TalerErrorCode.WALLET_CORE_API_OPERATION_UNKNOWN]: {}; - [TalerErrorCode.WALLET_HTTP_REQUEST_THROTTLED]: {}; - [TalerErrorCode.WALLET_HTTP_REQUEST_GENERIC_TIMEOUT]: {}; - [TalerErrorCode.WALLET_NETWORK_ERROR]: {}; - [TalerErrorCode.WALLET_RECEIVED_MALFORMED_RESPONSE]: {}; - [TalerErrorCode.WALLET_EXCHANGE_COIN_SIGNATURE_INVALID]: {}; - [TalerErrorCode.WALLET_WITHDRAWAL_GROUP_INCOMPLETE]: {}; - [TalerErrorCode.WALLET_CORE_NOT_AVAILABLE]: {}; - [TalerErrorCode.GENERIC_UNEXPECTED_REQUEST_ERROR]: {}; + [TalerErrorCode.WALLET_UNEXPECTED_REQUEST_ERROR]: { + requestUrl: string; + requestMethod: string; + httpStatusCode: number; + errorResponse?: any; + }; + [TalerErrorCode.WALLET_UNEXPECTED_EXCEPTION]: { + stack?: string; + }; + [TalerErrorCode.WALLET_BANK_INTEGRATION_PROTOCOL_VERSION_INCOMPATIBLE]: { + exchangeProtocolVersion: string; + walletProtocolVersion: string; + }; + [TalerErrorCode.WALLET_CORE_API_OPERATION_UNKNOWN]: { + operation: string; + }; + [TalerErrorCode.WALLET_HTTP_REQUEST_THROTTLED]: { + requestUrl: string; + requestMethod: string; + throttleStats: Record; + }; + [TalerErrorCode.WALLET_HTTP_REQUEST_GENERIC_TIMEOUT]: empty; + [TalerErrorCode.WALLET_NETWORK_ERROR]: { + requestUrl: string; + requestMethod: string; + }; + [TalerErrorCode.WALLET_RECEIVED_MALFORMED_RESPONSE]: { + requestUrl: string; + requestMethod: string; + httpStatusCode: number; + validationError?: string; + }; + [TalerErrorCode.WALLET_EXCHANGE_COIN_SIGNATURE_INVALID]: empty; + [TalerErrorCode.WALLET_WITHDRAWAL_GROUP_INCOMPLETE]: { + errorsPerCoin: Record; + }; + [TalerErrorCode.WALLET_CORE_NOT_AVAILABLE]: empty; + [TalerErrorCode.GENERIC_UNEXPECTED_REQUEST_ERROR]: { + httpStatusCode: number; + }; [TalerErrorCode.WALLET_PAY_MERCHANT_SERVER_ERROR]: { requestError: TalerErrorDetail; }; @@ -84,7 +114,7 @@ export interface DetailsMap { detail: string; }; [TalerErrorCode.WALLET_WITHDRAWAL_KYC_REQUIRED]: { - // FIXME! + kycUrl: string; }; [TalerErrorCode.WALLET_DEPOSIT_GROUP_INSUFFICIENT_BALANCE]: { insufficientBalanceDetails: PayMerchantInsufficientBalanceDetails; @@ -94,7 +124,7 @@ export interface DetailsMap { }; } -type ErrBody = Y extends keyof DetailsMap ? DetailsMap[Y] : never; +type ErrBody = Y extends keyof DetailsMap ? DetailsMap[Y] : empty; export function makeErrorDetail( code: C, @@ -133,7 +163,7 @@ function getDefaultHint(code: number): string { } } -export class TalerProtocolViolationError extends Error { +export class TalerProtocolViolationError extends Error { constructor(hint?: string) { let msg: string; if (hint) { diff --git a/packages/taler-wallet-core/src/operations/backup/index.ts b/packages/taler-wallet-core/src/operations/backup/index.ts index 27d27da0d..7d3953ebb 100644 --- a/packages/taler-wallet-core/src/operations/backup/index.ts +++ b/packages/taler-wallet-core/src/operations/backup/index.ts @@ -734,7 +734,7 @@ async function runFirstBackupCycleForProvider( case OperationAttemptResultType.Error: throw TalerError.fromDetail( TalerErrorCode.WALLET_UNEXPECTED_EXCEPTION, - resp.errorDetail, + resp.errorDetail as any, //FIXME create an error for backup problems ); case OperationAttemptResultType.Finished: return { diff --git a/packages/taler-wallet-core/src/util/http.ts b/packages/taler-wallet-core/src/util/http.ts index 118da40fe..1da31a315 100644 --- a/packages/taler-wallet-core/src/util/http.ts +++ b/packages/taler-wallet-core/src/util/http.ts @@ -68,7 +68,7 @@ export interface HttpRequestOptions { */ cancellationToken?: CancellationToken; - body?: string | ArrayBuffer | Object; + body?: string | ArrayBuffer | Record; } /** @@ -185,6 +185,7 @@ export async function readUnexpectedResponseDetails( TalerErrorCode.WALLET_UNEXPECTED_REQUEST_ERROR, { requestUrl: httpResponse.requestUrl, + requestMethod: httpResponse.requestMethod, httpStatusCode: httpResponse.status, errorResponse: errJson, }, @@ -211,6 +212,7 @@ export async function readSuccessResponseJsonOrErrorCode( TalerErrorCode.WALLET_RECEIVED_MALFORMED_RESPONSE, { requestUrl: httpResponse.requestUrl, + requestMethod: httpResponse.requestMethod, httpStatusCode: httpResponse.status, validationError: e.toString(), }, @@ -223,11 +225,18 @@ export async function readSuccessResponseJsonOrErrorCode( }; } +type HttpErrorDetails = { + requestUrl: string; + requestMethod: string; + httpStatusCode: number; +}; + export function getHttpResponseErrorDetails( httpResponse: HttpResponse, -): Record { +): HttpErrorDetails { return { requestUrl: httpResponse.requestUrl, + requestMethod: httpResponse.requestMethod, httpStatusCode: httpResponse.status, }; } @@ -240,6 +249,7 @@ export function throwUnexpectedRequestError( TalerErrorCode.WALLET_UNEXPECTED_REQUEST_ERROR, { requestUrl: httpResponse.requestUrl, + requestMethod: httpResponse.requestMethod, httpStatusCode: httpResponse.status, errorResponse: talerErrorResponse, }, diff --git a/packages/taler-wallet-webextension/src/browserHttpLib.ts b/packages/taler-wallet-webextension/src/browserHttpLib.ts index 26fa8eb11..165a0037c 100644 --- a/packages/taler-wallet-webextension/src/browserHttpLib.ts +++ b/packages/taler-wallet-webextension/src/browserHttpLib.ts @@ -90,7 +90,8 @@ export class BrowserHttpLib implements HttpRequestLibrary { TalerError.fromDetail( TalerErrorCode.WALLET_NETWORK_ERROR, { - requestUrl: requestUrl, + requestUrl, + requestMethod, }, "Could not make request", ), @@ -103,7 +104,8 @@ export class BrowserHttpLib implements HttpRequestLibrary { const exc = TalerError.fromDetail( TalerErrorCode.WALLET_NETWORK_ERROR, { - requestUrl: requestUrl, + requestUrl, + requestMethod, }, "HTTP request failed (status 0, maybe URI scheme was wrong?)", ); @@ -124,7 +126,8 @@ export class BrowserHttpLib implements HttpRequestLibrary { throw TalerError.fromDetail( TalerErrorCode.WALLET_RECEIVED_MALFORMED_RESPONSE, { - requestUrl: requestUrl, + requestUrl, + requestMethod, httpStatusCode: myRequest.status, }, "Invalid JSON from HTTP response", @@ -134,7 +137,8 @@ export class BrowserHttpLib implements HttpRequestLibrary { throw TalerError.fromDetail( TalerErrorCode.WALLET_RECEIVED_MALFORMED_RESPONSE, { - requestUrl: requestUrl, + requestUrl, + requestMethod, httpStatusCode: myRequest.status, }, "Invalid JSON from HTTP response", diff --git a/packages/taler-wallet-webextension/src/serviceWorkerHttpLib.ts b/packages/taler-wallet-webextension/src/serviceWorkerHttpLib.ts index 82d11a15a..4b47e89d5 100644 --- a/packages/taler-wallet-webextension/src/serviceWorkerHttpLib.ts +++ b/packages/taler-wallet-webextension/src/serviceWorkerHttpLib.ts @@ -104,8 +104,8 @@ export class ServiceWorkerHttpLib implements HttpRequestLibrary { status: response.status, requestMethod, requestUrl, - json: makeJsonHandler(response, requestUrl), - text: makeTextHandler(response, requestUrl), + json: makeJsonHandler(response, requestUrl, requestMethod), + text: makeTextHandler(response, requestUrl, requestMethod), bytes: async () => (await response.blob()).arrayBuffer(), }; } catch (e) { @@ -145,7 +145,11 @@ export class ServiceWorkerHttpLib implements HttpRequestLibrary { } } -function makeTextHandler(response: Response, requestUrl: string) { +function makeTextHandler( + response: Response, + requestUrl: string, + requestMethod: string, +) { return async function getJsonFromResponse(): Promise { let respText; try { @@ -155,6 +159,7 @@ function makeTextHandler(response: Response, requestUrl: string) { TalerErrorCode.WALLET_RECEIVED_MALFORMED_RESPONSE, { requestUrl, + requestMethod, httpStatusCode: response.status, }, "Invalid JSON from HTTP response", @@ -164,7 +169,11 @@ function makeTextHandler(response: Response, requestUrl: string) { }; } -function makeJsonHandler(response: Response, requestUrl: string) { +function makeJsonHandler( + response: Response, + requestUrl: string, + requestMethod: string, +) { return async function getJsonFromResponse(): Promise { let responseJson; try { @@ -174,6 +183,7 @@ function makeJsonHandler(response: Response, requestUrl: string) { TalerErrorCode.WALLET_RECEIVED_MALFORMED_RESPONSE, { requestUrl, + requestMethod, httpStatusCode: response.status, }, "Invalid JSON from HTTP response", @@ -184,6 +194,7 @@ function makeJsonHandler(response: Response, requestUrl: string) { TalerErrorCode.WALLET_RECEIVED_MALFORMED_RESPONSE, { requestUrl, + requestMethod, httpStatusCode: response.status, }, "Invalid JSON from HTTP response", -- cgit v1.2.3