stronger type check to be sure that ErrorDetails is consistent

This commit is contained in:
Sebastian 2023-01-17 15:58:20 -03:00
parent 5be2d128ed
commit eeea3e62a0
No known key found for this signature in database
GPG Key ID: BE4FF68352439FC1
5 changed files with 84 additions and 29 deletions

View File

@ -32,6 +32,8 @@ import {
TransactionType,
} from "@gnu-taler/taler-util";
type empty = Record<string, never>;
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<string, unknown>;
};
[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<number, TalerErrorDetail>;
};
[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> = Y extends keyof DetailsMap ? DetailsMap[Y] : never;
type ErrBody<Y> = Y extends keyof DetailsMap ? DetailsMap[Y] : empty;
export function makeErrorDetail<C extends TalerErrorCode>(
code: C,
@ -133,7 +163,7 @@ function getDefaultHint(code: number): string {
}
}
export class TalerProtocolViolationError<T = any> extends Error {
export class TalerProtocolViolationError extends Error {
constructor(hint?: string) {
let msg: string;
if (hint) {

View File

@ -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 {

View File

@ -68,7 +68,7 @@ export interface HttpRequestOptions {
*/
cancellationToken?: CancellationToken;
body?: string | ArrayBuffer | Object;
body?: string | ArrayBuffer | Record<string, unknown>;
}
/**
@ -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<T>(
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<T>(
};
}
type HttpErrorDetails = {
requestUrl: string;
requestMethod: string;
httpStatusCode: number;
};
export function getHttpResponseErrorDetails(
httpResponse: HttpResponse,
): Record<string, unknown> {
): 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,
},

View File

@ -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",

View File

@ -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<any> {
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<any> {
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",