aboutsummaryrefslogtreecommitdiff
path: root/packages/taler-wallet-core/src/errors.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/taler-wallet-core/src/errors.ts')
-rw-r--r--packages/taler-wallet-core/src/errors.ts248
1 files changed, 0 insertions, 248 deletions
diff --git a/packages/taler-wallet-core/src/errors.ts b/packages/taler-wallet-core/src/errors.ts
deleted file mode 100644
index 038bdbc7c..000000000
--- a/packages/taler-wallet-core/src/errors.ts
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- This file is part of GNU Taler
- (C) 2019-2020 Taler Systems SA
-
- GNU Taler is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
- */
-
-/**
- * Classes and helpers for error handling specific to wallet operations.
- *
- * @author Florian Dold <dold@taler.net>
- */
-
-/**
- * Imports.
- */
-import {
- AbsoluteTime,
- PayMerchantInsufficientBalanceDetails,
- PayPeerInsufficientBalanceDetails,
- TalerErrorCode,
- TalerErrorDetail,
- TransactionType,
-} from "@gnu-taler/taler-util";
-
-type empty = Record<string, never>;
-
-export interface DetailsMap {
- [TalerErrorCode.WALLET_PENDING_OPERATION_FAILED]: {
- innerError: TalerErrorDetail;
- transactionId?: string;
- };
- [TalerErrorCode.WALLET_EXCHANGE_DENOMINATIONS_INSUFFICIENT]: {
- exchangeBaseUrl: string;
- };
- [TalerErrorCode.WALLET_EXCHANGE_PROTOCOL_VERSION_INCOMPATIBLE]: {
- exchangeProtocolVersion: string;
- walletProtocolVersion: string;
- };
- [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]: empty;
- [TalerErrorCode.WALLET_CONTRACT_TERMS_SIGNATURE_INVALID]: {
- merchantPub: string;
- orderId: string;
- };
- [TalerErrorCode.WALLET_CONTRACT_TERMS_BASE_URL_MISMATCH]: {
- baseUrlForDownload: string;
- baseUrlFromContractTerms: string;
- };
- [TalerErrorCode.WALLET_INVALID_TALER_PAY_URI]: {
- talerPayUri: string;
- };
- [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;
- };
- [TalerErrorCode.WALLET_CRYPTO_WORKER_ERROR]: {
- innerError: TalerErrorDetail;
- };
- [TalerErrorCode.WALLET_CRYPTO_WORKER_BAD_REQUEST]: {
- detail: string;
- };
- [TalerErrorCode.WALLET_WITHDRAWAL_KYC_REQUIRED]: {
- kycUrl: string;
- };
- [TalerErrorCode.WALLET_DEPOSIT_GROUP_INSUFFICIENT_BALANCE]: {
- insufficientBalanceDetails: PayMerchantInsufficientBalanceDetails;
- };
- [TalerErrorCode.WALLET_PEER_PUSH_PAYMENT_INSUFFICIENT_BALANCE]: {
- insufficientBalanceDetails: PayPeerInsufficientBalanceDetails;
- };
-}
-
-type ErrBody<Y> = Y extends keyof DetailsMap ? DetailsMap[Y] : empty;
-
-export function makeErrorDetail<C extends TalerErrorCode>(
- code: C,
- detail: ErrBody<C>,
- hint?: string,
-): TalerErrorDetail {
- if (!hint && !(detail as any).hint) {
- hint = getDefaultHint(code);
- }
- const when = AbsoluteTime.now();
- return { code, when, hint, ...detail };
-}
-
-export function makePendingOperationFailedError(
- innerError: TalerErrorDetail,
- tag: TransactionType,
- uid: string,
-): TalerError {
- return TalerError.fromDetail(TalerErrorCode.WALLET_PENDING_OPERATION_FAILED, {
- innerError,
- transactionId: `${tag}:${uid}`,
- });
-}
-
-export function summarizeTalerErrorDetail(ed: TalerErrorDetail): string {
- const errName = TalerErrorCode[ed.code] ?? "<unknown>";
- return `Error (${ed.code}/${errName})`;
-}
-
-function getDefaultHint(code: number): string {
- const errName = TalerErrorCode[code];
- if (errName) {
- return `Error (${errName})`;
- } else {
- return `Error (<unknown>)`;
- }
-}
-
-export class TalerProtocolViolationError extends Error {
- constructor(hint?: string) {
- let msg: string;
- if (hint) {
- msg = `Taler protocol violation error (${hint})`;
- } else {
- msg = `Taler protocol violation error`;
- }
- super(msg);
- Object.setPrototypeOf(this, TalerProtocolViolationError.prototype);
- }
-}
-
-export class TalerError<T = any> extends Error {
- errorDetail: TalerErrorDetail & T;
- private constructor(d: TalerErrorDetail & T) {
- super(d.hint ?? `Error (code ${d.code})`);
- this.errorDetail = d;
- Object.setPrototypeOf(this, TalerError.prototype);
- }
-
- static fromDetail<C extends TalerErrorCode>(
- code: C,
- detail: ErrBody<C>,
- hint?: string,
- ): TalerError {
- if (!hint) {
- hint = getDefaultHint(code);
- }
- const when = AbsoluteTime.now();
- return new TalerError<unknown>({ code, when, hint, ...detail });
- }
-
- static fromUncheckedDetail(d: TalerErrorDetail): TalerError {
- return new TalerError<unknown>({ ...d });
- }
-
- static fromException(e: any): TalerError {
- const errDetail = getErrorDetailFromException(e);
- return new TalerError(errDetail);
- }
-
- hasErrorCode<C extends keyof DetailsMap>(
- code: C,
- ): this is TalerError<DetailsMap[C]> {
- return this.errorDetail.code === code;
- }
-}
-
-/**
- * Convert an exception (or anything that was thrown) into
- * a TalerErrorDetail object.
- */
-export function getErrorDetailFromException(e: any): TalerErrorDetail {
- if (e instanceof TalerError) {
- return e.errorDetail;
- }
- if (e instanceof Error) {
- const err = makeErrorDetail(
- TalerErrorCode.WALLET_UNEXPECTED_EXCEPTION,
- {
- stack: e.stack,
- },
- `unexpected exception (message: ${e.message})`,
- );
- return err;
- }
- // Something was thrown that is not even an exception!
- // Try to stringify it.
- let excString: string;
- try {
- excString = e.toString();
- } catch (e) {
- // Something went horribly wrong.
- excString = "can't stringify exception";
- }
- const err = makeErrorDetail(
- TalerErrorCode.WALLET_UNEXPECTED_EXCEPTION,
- {},
- `unexpected exception (not an exception, ${excString})`,
- );
- return err;
-}