aboutsummaryrefslogtreecommitdiff
path: root/packages/taler-wallet-webextension
diff options
context:
space:
mode:
authorFlorian Dold <florian@dold.me>2022-03-22 21:16:38 +0100
committerFlorian Dold <florian@dold.me>2022-03-22 21:16:38 +0100
commit5d23eb36354d07508a015531f298b3e261bbafce (patch)
treefae0d2599c94d88c9264bb63a301adb1706824c1 /packages/taler-wallet-webextension
parentf8d12f7b0d4af1b1769b89e80c87f9c169678564 (diff)
wallet: improve error handling and error codes
Diffstat (limited to 'packages/taler-wallet-webextension')
-rw-r--r--packages/taler-wallet-webextension/src/browserHttpLib.ts22
-rw-r--r--packages/taler-wallet-webextension/src/components/ErrorTalerOperation.tsx6
-rw-r--r--packages/taler-wallet-webextension/src/cta/Deposit.tsx14
-rw-r--r--packages/taler-wallet-webextension/src/cta/Pay.tsx4
-rw-r--r--packages/taler-wallet-webextension/src/cta/Withdraw.tsx13
-rw-r--r--packages/taler-wallet-webextension/src/hooks/useAsyncAsHook.ts30
-rw-r--r--packages/taler-wallet-webextension/src/serviceWorkerHttpLib.ts18
-rw-r--r--packages/taler-wallet-webextension/src/wxApi.ts73
-rw-r--r--packages/taler-wallet-webextension/src/wxBackend.ts11
9 files changed, 120 insertions, 71 deletions
diff --git a/packages/taler-wallet-webextension/src/browserHttpLib.ts b/packages/taler-wallet-webextension/src/browserHttpLib.ts
index 8877edfc3..53ab85598 100644
--- a/packages/taler-wallet-webextension/src/browserHttpLib.ts
+++ b/packages/taler-wallet-webextension/src/browserHttpLib.ts
@@ -18,11 +18,11 @@
* Imports.
*/
import {
- OperationFailedError,
HttpRequestLibrary,
HttpRequestOptions,
HttpResponse,
Headers,
+ TalerError,
} from "@gnu-taler/taler-wallet-core";
import {
Logger,
@@ -49,14 +49,14 @@ export class BrowserHttpLib implements HttpRequestLibrary {
if (this.throttlingEnabled && this.throttle.applyThrottle(requestUrl)) {
const parsedUrl = new URL(requestUrl);
- throw OperationFailedError.fromCode(
+ throw TalerError.fromDetail(
TalerErrorCode.WALLET_HTTP_REQUEST_THROTTLED,
- `request to origin ${parsedUrl.origin} was throttled`,
{
requestMethod,
requestUrl,
throttleStats: this.throttle.getThrottleStats(requestUrl),
},
+ `request to origin ${parsedUrl.origin} was throttled`,
);
}
@@ -78,12 +78,12 @@ export class BrowserHttpLib implements HttpRequestLibrary {
myRequest.onerror = (e) => {
logger.error("http request error");
reject(
- OperationFailedError.fromCode(
+ TalerError.fromDetail(
TalerErrorCode.WALLET_NETWORK_ERROR,
- "Could not make request",
{
requestUrl: requestUrl,
},
+ "Could not make request",
),
);
};
@@ -91,12 +91,12 @@ export class BrowserHttpLib implements HttpRequestLibrary {
myRequest.addEventListener("readystatechange", (e) => {
if (myRequest.readyState === XMLHttpRequest.DONE) {
if (myRequest.status === 0) {
- const exc = OperationFailedError.fromCode(
+ const exc = TalerError.fromDetail(
TalerErrorCode.WALLET_NETWORK_ERROR,
- "HTTP request failed (status 0, maybe URI scheme was wrong?)",
{
requestUrl: requestUrl,
},
+ "HTTP request failed (status 0, maybe URI scheme was wrong?)",
);
reject(exc);
return;
@@ -112,23 +112,23 @@ export class BrowserHttpLib implements HttpRequestLibrary {
const responseString = td.decode(myRequest.response);
responseJson = JSON.parse(responseString);
} catch (e) {
- throw OperationFailedError.fromCode(
+ throw TalerError.fromDetail(
TalerErrorCode.WALLET_RECEIVED_MALFORMED_RESPONSE,
- "Invalid JSON from HTTP response",
{
requestUrl: requestUrl,
httpStatusCode: myRequest.status,
},
+ "Invalid JSON from HTTP response",
);
}
if (responseJson === null || typeof responseJson !== "object") {
- throw OperationFailedError.fromCode(
+ throw TalerError.fromDetail(
TalerErrorCode.WALLET_RECEIVED_MALFORMED_RESPONSE,
- "Invalid JSON from HTTP response",
{
requestUrl: requestUrl,
httpStatusCode: myRequest.status,
},
+ "Invalid JSON from HTTP response",
);
}
return responseJson;
diff --git a/packages/taler-wallet-webextension/src/components/ErrorTalerOperation.tsx b/packages/taler-wallet-webextension/src/components/ErrorTalerOperation.tsx
index 356709091..38d6ec561 100644
--- a/packages/taler-wallet-webextension/src/components/ErrorTalerOperation.tsx
+++ b/packages/taler-wallet-webextension/src/components/ErrorTalerOperation.tsx
@@ -13,7 +13,7 @@
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/>
*/
-import { TalerErrorDetails } from "@gnu-taler/taler-util";
+import { TalerErrorDetail } from "@gnu-taler/taler-util";
import { Fragment, h, VNode } from "preact";
import { useState } from "preact/hooks";
import arrowDown from "../../static/img/chevron-down.svg";
@@ -25,7 +25,7 @@ export function ErrorTalerOperation({
error,
}: {
title?: VNode;
- error?: TalerErrorDetails;
+ error?: TalerErrorDetail;
}): VNode | null {
const { devMode } = useDevContext();
const [showErrorDetail, setShowErrorDetail] = useState(false);
@@ -59,7 +59,7 @@ export function ErrorTalerOperation({
<Fragment>
<div style={{ padding: 5, textAlign: "left" }}>
<div>
- <b>{error.message}</b> {!errorHint ? "" : `: ${errorHint}`}{" "}
+ <b>{error.hint}</b> {!errorHint ? "" : `: ${errorHint}`}{" "}
</div>
</div>
{devMode && (
diff --git a/packages/taler-wallet-webextension/src/cta/Deposit.tsx b/packages/taler-wallet-webextension/src/cta/Deposit.tsx
index ac6c1fd6d..933195a9e 100644
--- a/packages/taler-wallet-webextension/src/cta/Deposit.tsx
+++ b/packages/taler-wallet-webextension/src/cta/Deposit.tsx
@@ -35,7 +35,7 @@ import {
PreparePayResultType,
Translate,
} from "@gnu-taler/taler-util";
-import { OperationFailedError } from "@gnu-taler/taler-wallet-core";
+import { TalerError } from "@gnu-taler/taler-wallet-core";
import { Fragment, h, VNode } from "preact";
import { useEffect, useState } from "preact/hooks";
import { ErrorTalerOperation } from "../components/ErrorTalerOperation";
@@ -64,9 +64,9 @@ export function DepositPage({ talerPayUri, goBack }: Props): VNode {
const [payResult, setPayResult] = useState<ConfirmPayResult | undefined>(
undefined,
);
- const [payErrMsg, setPayErrMsg] = useState<
- OperationFailedError | string | undefined
- >(undefined);
+ const [payErrMsg, setPayErrMsg] = useState<TalerError | string | undefined>(
+ undefined,
+ );
const balance = useAsyncAsHook(wxApi.getBalance, [
NotificationType.CoinWithdrawn,
@@ -97,7 +97,7 @@ export function DepositPage({ talerPayUri, goBack }: Props): VNode {
setPayStatus(p);
} catch (e) {
console.log("Got error while trying to pay", e);
- if (e instanceof OperationFailedError) {
+ if (e instanceof TalerError) {
setPayErrMsg(e);
}
if (e instanceof Error) {
@@ -117,7 +117,7 @@ export function DepositPage({ talerPayUri, goBack }: Props): VNode {
}
if (!payStatus) {
- if (payErrMsg instanceof OperationFailedError) {
+ if (payErrMsg instanceof TalerError) {
return (
<WalletAction>
<LogoHeader />
@@ -131,7 +131,7 @@ export function DepositPage({ talerPayUri, goBack }: Props): VNode {
Could not get the payment information for this order
</i18n.Translate>
}
- error={payErrMsg?.operationError}
+ error={payErrMsg?.errorDetail}
/>
</section>
</WalletAction>
diff --git a/packages/taler-wallet-webextension/src/cta/Pay.tsx b/packages/taler-wallet-webextension/src/cta/Pay.tsx
index 2a0d1b46b..f6ae02f72 100644
--- a/packages/taler-wallet-webextension/src/cta/Pay.tsx
+++ b/packages/taler-wallet-webextension/src/cta/Pay.tsx
@@ -36,7 +36,7 @@ import {
PreparePayResultType,
Product,
} from "@gnu-taler/taler-util";
-import { OperationFailedError } from "@gnu-taler/taler-wallet-core";
+import { TalerError } from "@gnu-taler/taler-wallet-core";
import { Fragment, h, VNode } from "preact";
import { useEffect, useState } from "preact/hooks";
import { ErrorMessage } from "../components/ErrorMessage";
@@ -93,7 +93,7 @@ export function PayPage({
undefined,
);
const [payErrMsg, setPayErrMsg] = useState<
- OperationFailedError | string | undefined
+ TalerError | string | undefined
>(undefined);
const hook = useAsyncAsHook(async () => {
diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw.tsx b/packages/taler-wallet-webextension/src/cta/Withdraw.tsx
index 66c83cf15..d58e2ec80 100644
--- a/packages/taler-wallet-webextension/src/cta/Withdraw.tsx
+++ b/packages/taler-wallet-webextension/src/cta/Withdraw.tsx
@@ -25,10 +25,8 @@ import {
AmountJson,
Amounts,
ExchangeListItem,
- Translate,
WithdrawUriInfoResponse,
} from "@gnu-taler/taler-util";
-import { OperationFailedError } from "@gnu-taler/taler-wallet-core";
import { Fragment, h, VNode } from "preact";
import { useState } from "preact/hooks";
import { Loading } from "../components/Loading";
@@ -52,6 +50,7 @@ import {
import * as wxApi from "../wxApi";
import { TermsOfServiceSection } from "./TermsOfServiceSection";
import { useTranslationContext } from "../context/translation";
+import { TalerError } from "@gnu-taler/taler-wallet-core";
interface Props {
talerWithdrawUri?: string;
@@ -85,9 +84,9 @@ export function View({
reviewed,
}: ViewProps): VNode {
const { i18n } = useTranslationContext();
- const [withdrawError, setWithdrawError] = useState<
- OperationFailedError | undefined
- >(undefined);
+ const [withdrawError, setWithdrawError] = useState<TalerError | undefined>(
+ undefined,
+ );
const [confirmDisabled, setConfirmDisabled] = useState<boolean>(false);
const needsReview = terms.status === "changed" || terms.status === "new";
@@ -109,7 +108,7 @@ export function View({
setConfirmDisabled(true);
await onWithdraw();
} catch (e) {
- if (e instanceof OperationFailedError) {
+ if (e instanceof TalerError) {
setWithdrawError(e);
}
setConfirmDisabled(false);
@@ -130,7 +129,7 @@ export function View({
Could not finish the withdrawal operation
</i18n.Translate>
}
- error={withdrawError.operationError}
+ error={withdrawError.errorDetail}
/>
)}
diff --git a/packages/taler-wallet-webextension/src/hooks/useAsyncAsHook.ts b/packages/taler-wallet-webextension/src/hooks/useAsyncAsHook.ts
index 6efa1d181..8d31de94f 100644
--- a/packages/taler-wallet-webextension/src/hooks/useAsyncAsHook.ts
+++ b/packages/taler-wallet-webextension/src/hooks/useAsyncAsHook.ts
@@ -13,28 +13,32 @@
You should have received a copy of the GNU General Public License along with
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
-import { NotificationType, TalerErrorDetails } from "@gnu-taler/taler-util";
+import {
+ NotificationType,
+ TalerErrorCode,
+ TalerErrorDetail,
+} from "@gnu-taler/taler-util";
+import { TalerError } from "@gnu-taler/taler-wallet-core";
import { useEffect, useState } from "preact/hooks";
import * as wxApi from "../wxApi";
-import { OperationFailedError } from "@gnu-taler/taler-wallet-core";
interface HookOk<T> {
hasError: false;
response: T;
}
-export type HookError = HookGenericError | HookOperationalError
+export type HookError = HookGenericError | HookOperationalError;
export interface HookGenericError {
hasError: true;
- operational: false,
+ operational: false;
message: string;
}
export interface HookOperationalError {
hasError: true;
- operational: true,
- details: TalerErrorDetails;
+ operational: true;
+ details: TalerErrorDetail;
}
export type HookResponse<T> = HookOk<T> | HookError | undefined;
@@ -51,10 +55,18 @@ export function useAsyncAsHook<T>(
const response = await fn();
setHookResponse({ hasError: false, response });
} catch (e) {
- if (e instanceof OperationFailedError) {
- setHookResponse({ hasError: true, operational: true, details: e.operationError });
+ if (e instanceof TalerError) {
+ setHookResponse({
+ hasError: true,
+ operational: true,
+ details: e.errorDetail,
+ });
} else if (e instanceof Error) {
- setHookResponse({ hasError: true, operational: false, message: e.message });
+ setHookResponse({
+ hasError: true,
+ operational: false,
+ message: e.message,
+ });
}
}
}
diff --git a/packages/taler-wallet-webextension/src/serviceWorkerHttpLib.ts b/packages/taler-wallet-webextension/src/serviceWorkerHttpLib.ts
index 6f2585c1e..4dee28a6c 100644
--- a/packages/taler-wallet-webextension/src/serviceWorkerHttpLib.ts
+++ b/packages/taler-wallet-webextension/src/serviceWorkerHttpLib.ts
@@ -23,7 +23,7 @@ import {
HttpRequestLibrary,
HttpRequestOptions,
HttpResponse,
- OperationFailedError,
+ TalerError,
} from "@gnu-taler/taler-wallet-core";
/**
@@ -44,14 +44,14 @@ export class ServiceWorkerHttpLib implements HttpRequestLibrary {
if (this.throttlingEnabled && this.throttle.applyThrottle(requestUrl)) {
const parsedUrl = new URL(requestUrl);
- throw OperationFailedError.fromCode(
+ throw TalerError.fromDetail(
TalerErrorCode.WALLET_HTTP_REQUEST_THROTTLED,
- `request to origin ${parsedUrl.origin} was throttled`,
{
requestMethod,
requestUrl,
throttleStats: this.throttle.getThrottleStats(requestUrl),
},
+ `request to origin ${parsedUrl.origin} was throttled`,
);
}
@@ -107,13 +107,13 @@ function makeTextHandler(response: Response, requestUrl: string) {
try {
respText = await response.text();
} catch (e) {
- throw OperationFailedError.fromCode(
+ throw TalerError.fromDetail(
TalerErrorCode.WALLET_RECEIVED_MALFORMED_RESPONSE,
- "Invalid JSON from HTTP response",
{
requestUrl,
httpStatusCode: response.status,
},
+ "Invalid JSON from HTTP response",
);
}
return respText;
@@ -126,23 +126,23 @@ function makeJsonHandler(response: Response, requestUrl: string) {
try {
responseJson = await response.json();
} catch (e) {
- throw OperationFailedError.fromCode(
+ throw TalerError.fromDetail(
TalerErrorCode.WALLET_RECEIVED_MALFORMED_RESPONSE,
- "Invalid JSON from HTTP response",
{
requestUrl,
httpStatusCode: response.status,
},
+ "Invalid JSON from HTTP response",
);
}
if (responseJson === null || typeof responseJson !== "object") {
- throw OperationFailedError.fromCode(
+ throw TalerError.fromDetail(
TalerErrorCode.WALLET_RECEIVED_MALFORMED_RESPONSE,
- "Invalid JSON from HTTP response",
{
requestUrl,
httpStatusCode: response.status,
},
+ "Invalid JSON from HTTP response",
);
}
return responseJson;
diff --git a/packages/taler-wallet-webextension/src/wxApi.ts b/packages/taler-wallet-webextension/src/wxApi.ts
index 31b46d88d..2071f85e5 100644
--- a/packages/taler-wallet-webextension/src/wxApi.ts
+++ b/packages/taler-wallet-webextension/src/wxApi.ts
@@ -23,26 +23,48 @@
*/
import {
AcceptExchangeTosRequest,
- AcceptManualWithdrawalResult, AcceptTipRequest, AcceptWithdrawalResponse,
- AddExchangeRequest, AmountString, ApplyRefundResponse, BalancesResponse, CoinDumpJson, ConfirmPayResult,
- CoreApiResponse, CreateDepositGroupRequest, CreateDepositGroupResponse, DeleteTransactionRequest, ExchangesListRespose,
- GetExchangeTosResult, GetExchangeWithdrawalInfo,
+ AcceptManualWithdrawalResult,
+ AcceptTipRequest,
+ AcceptWithdrawalResponse,
+ AddExchangeRequest,
+ AmountString,
+ ApplyRefundResponse,
+ BalancesResponse,
+ CoinDumpJson,
+ ConfirmPayResult,
+ CoreApiResponse,
+ CreateDepositGroupRequest,
+ CreateDepositGroupResponse,
+ DeleteTransactionRequest,
+ ExchangesListRespose,
+ GetExchangeTosResult,
+ GetExchangeWithdrawalInfo,
GetFeeForDepositRequest,
- GetWithdrawalDetailsForUriRequest, KnownBankAccounts, NotificationType, PreparePayResult, PrepareTipRequest,
- PrepareTipResult, RetryTransactionRequest,
- SetWalletDeviceIdRequest, TransactionsResponse, WalletDiagnostics, WithdrawUriInfoResponse
+ GetWithdrawalDetailsForUriRequest,
+ KnownBankAccounts,
+ NotificationType,
+ PreparePayResult,
+ PrepareTipRequest,
+ PrepareTipResult,
+ RetryTransactionRequest,
+ SetWalletDeviceIdRequest,
+ TransactionsResponse,
+ WalletDiagnostics,
+ WithdrawUriInfoResponse,
} from "@gnu-taler/taler-util";
import {
- AddBackupProviderRequest, BackupInfo, OperationFailedError,
+ AddBackupProviderRequest,
+ BackupInfo,
PendingOperationsResponse,
- RemoveBackupProviderRequest
+ RemoveBackupProviderRequest,
+ TalerError,
} from "@gnu-taler/taler-wallet-core";
import { DepositFee } from "@gnu-taler/taler-wallet-core/src/operations/deposits";
import type { ExchangeWithdrawDetails } from "@gnu-taler/taler-wallet-core/src/operations/withdraw";
import { MessageFromBackend } from "./wxBackend";
/**
- *
+ *
* @autor Florian Dold
* @autor sebasjm
*/
@@ -88,7 +110,7 @@ async function callBackend(operation: string, payload: any): Promise<any> {
console.log("got response", resp);
const r = resp as CoreApiResponse;
if (r.type === "error") {
- reject(new OperationFailedError(r.error));
+ reject(TalerError.fromUncheckedDetail(r.error));
return;
}
resolve(r.result);
@@ -127,15 +149,23 @@ export function resetDb(): Promise<void> {
return callBackend("reset-db", {});
}
-export function getFeeForDeposit(depositPaytoUri: string, amount: AmountString): Promise<DepositFee> {
+export function getFeeForDeposit(
+ depositPaytoUri: string,
+ amount: AmountString,
+): Promise<DepositFee> {
return callBackend("getFeeForDeposit", {
- depositPaytoUri, amount
+ depositPaytoUri,
+ amount,
} as GetFeeForDepositRequest);
}
-export function createDepositGroup(depositPaytoUri: string, amount: AmountString): Promise<CreateDepositGroupResponse> {
+export function createDepositGroup(
+ depositPaytoUri: string,
+ amount: AmountString,
+): Promise<CreateDepositGroupResponse> {
return callBackend("createDepositGroup", {
- depositPaytoUri, amount
+ depositPaytoUri,
+ amount,
} as CreateDepositGroupRequest);
}
@@ -190,7 +220,9 @@ export function listKnownCurrencies(): Promise<ListOfKnownCurrencies> {
export function listExchanges(): Promise<ExchangesListRespose> {
return callBackend("listExchanges", {});
}
-export function listKnownBankAccounts(currency?: string): Promise<KnownBankAccounts> {
+export function listKnownBankAccounts(
+ currency?: string,
+): Promise<KnownBankAccounts> {
return callBackend("listKnownBankAccounts", { currency });
}
@@ -387,14 +419,17 @@ export function exportDB(): Promise<any> {
}
export function importDB(dump: any): Promise<void> {
- return callBackend("importDb", { dump })
+ return callBackend("importDb", { dump });
}
-export function onUpdateNotification(messageTypes: Array<NotificationType>, doCallback: () => void): () => void {
+export function onUpdateNotification(
+ messageTypes: Array<NotificationType>,
+ doCallback: () => void,
+): () => void {
// eslint-disable-next-line no-undef
const port = chrome.runtime.connect({ name: "notifications" });
const listener = (message: MessageFromBackend): void => {
- const shouldNotify = messageTypes.includes(message.type)
+ const shouldNotify = messageTypes.includes(message.type);
if (shouldNotify) {
doCallback();
}
diff --git a/packages/taler-wallet-webextension/src/wxBackend.ts b/packages/taler-wallet-webextension/src/wxBackend.ts
index e158d2946..b7a0cdc54 100644
--- a/packages/taler-wallet-webextension/src/wxBackend.ts
+++ b/packages/taler-wallet-webextension/src/wxBackend.ts
@@ -35,7 +35,7 @@ import {
import {
DbAccess,
deleteTalerDatabase,
- makeErrorDetails,
+ makeErrorDetail,
OpenedPromise,
openPromise,
openTalerDatabase,
@@ -167,10 +167,10 @@ async function dispatch(
type: "error",
id: req.id,
operation: req.operation,
- error: makeErrorDetails(
+ error: makeErrorDetail(
TalerErrorCode.WALLET_CORE_NOT_AVAILABLE,
- "wallet core not available",
{},
+ "wallet core not available",
),
};
break;
@@ -233,7 +233,10 @@ function makeSyncWalletRedirect(
const tab = await getTab(tabId);
if (tab.url === oldUrl) {
console.log("redirecting to", innerUrl.href);
- chrome.tabs.update(tabId, { url: innerUrl.href, loadReplace: true } as any);
+ chrome.tabs.update(tabId, {
+ url: innerUrl.href,
+ loadReplace: true,
+ } as any);
}
};
doit();