show better info on transaction error

This commit is contained in:
Sebastian 2021-11-29 14:11:32 -03:00
parent d35f906ecb
commit a51333b693
No known key found for this signature in database
GPG Key ID: BE4FF68352439FC1
5 changed files with 98 additions and 25 deletions

View File

@ -24,7 +24,7 @@ export function ErrorMessage({
}: {
title?: string | VNode;
description?: string;
}) {
}): VNode | null {
const [showErrorDetail, setShowErrorDetail] = useState(false);
if (!title) return null;
return (

View File

@ -0,0 +1,63 @@
/*
This file is part of GNU Taler
(C) 2019 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/>
*/
import { TalerErrorDetails } from "@gnu-taler/taler-util";
import { VNode, h, Fragment } from "preact";
import { useState } from "preact/hooks";
import arrowDown from "../../static/img/chevron-down.svg";
import { ErrorBox } from "./styled";
export function ErrorTalerOperation({
title,
error,
}: {
title?: string;
error?: TalerErrorDetails;
}): VNode | null {
const [showErrorDetail, setShowErrorDetail] = useState(false);
const [showExtraInfo, setShowExtraInfo] = useState(false);
if (!title || !error) return null;
return (
<ErrorBox style={{ paddingTop: 0, paddingBottom: 0 }}>
<div>
<p>{title}</p>
{error && (
<button
onClick={() => {
setShowErrorDetail((v) => !v);
}}
>
<img style={{ height: "1.5em" }} src={arrowDown} />
</button>
)}
</div>
{showErrorDetail && (
<Fragment>
<div style={{ padding: 5, textAlign: "left" }}>
<div>{error.message}</div>
<a href="#" onClick={() => setShowExtraInfo((v) => !v)}>
more
</a>
</div>
{showExtraInfo && (
<div style={{ textAlign: "left", overflowX: "auto" }}>
<pre>{JSON.stringify(error, undefined, 2)}</pre>
</div>
)}
</Fragment>
)}
</ErrorBox>
);
}

View File

@ -36,8 +36,10 @@ import {
PreparePayResult,
PreparePayResultType,
} from "@gnu-taler/taler-util";
import { OperationFailedError } from "@gnu-taler/taler-wallet-core";
import { Fragment, h, VNode } from "preact";
import { useEffect, useState } from "preact/hooks";
import { ErrorTalerOperation } from "../components/ErrorTalerOperation";
import { LogoHeader } from "../components/LogoHeader";
import { Part } from "../components/Part";
import { QR } from "../components/QR";
@ -107,7 +109,9 @@ export function PayPage({ talerPayUri }: Props): VNode {
const [payResult, setPayResult] = useState<ConfirmPayResult | undefined>(
undefined,
);
const [payErrMsg, setPayErrMsg] = useState<string | undefined>(undefined);
const [payErrMsg, setPayErrMsg] = useState<
OperationFailedError | string | undefined
>(undefined);
const balance = useAsyncAsHook(wxApi.getBalance);
const balanceWithoutError = balance?.hasError
@ -131,6 +135,9 @@ export function PayPage({ talerPayUri }: Props): VNode {
const p = await wxApi.preparePay(talerPayUri);
setPayStatus(p);
} catch (e) {
if (e instanceof OperationFailedError) {
setPayErrMsg(e);
}
if (e instanceof Error) {
setPayErrMsg(e.message);
}
@ -144,6 +151,20 @@ export function PayPage({ talerPayUri }: Props): VNode {
}
if (!payStatus) {
if (payErrMsg instanceof OperationFailedError) {
return (
<WalletAction>
<LogoHeader />
<h2>{i18n.str`Digital cash payment`}</h2>
<section>
<ErrorTalerOperation
title="Could not get the payment information for this order"
error={payErrMsg?.operationError}
/>
</section>
</WalletAction>
);
}
if (payErrMsg) {
return (
<WalletAction>
@ -177,7 +198,6 @@ export function PayPage({ talerPayUri }: Props): VNode {
payStatus={payStatus}
payResult={payResult}
onClick={onClick}
payErrMsg={payErrMsg}
balance={foundAmount}
/>
);
@ -196,7 +216,6 @@ export function PaymentRequestView({
payStatus,
payResult,
onClick,
payErrMsg,
balance,
}: PaymentRequestViewProps): VNode {
let totalFees: AmountJson = Amounts.getZero(payStatus.amountRaw);
@ -218,12 +237,12 @@ export function PaymentRequestView({
totalFees = Amounts.sub(amountEffective, amountRaw).amount;
}
let merchantName: VNode;
if (contractTerms.merchant && contractTerms.merchant.name) {
merchantName = <strong>{contractTerms.merchant.name}</strong>;
} else {
merchantName = <strong>(pub: {contractTerms.merchant_pub})</strong>;
}
// let merchantName: VNode;
// if (contractTerms.merchant && contractTerms.merchant.name) {
// merchantName = <strong>{contractTerms.merchant.name}</strong>;
// } else {
// merchantName = <strong>(pub: {contractTerms.merchant_pub})</strong>;
// }
function Alternative(): VNode {
const [showQR, setShowQR] = useState<boolean>(false);
@ -259,18 +278,6 @@ export function PaymentRequestView({
}
return <Fragment />;
}
if (payErrMsg) {
return (
<section>
<div>
<p>Payment failed: {payErrMsg}</p>
<button class="pure-button button-success" onClick={onClick}>
{i18n.str`Retry`}
</button>
</div>
</section>
);
}
if (payStatus.status === PreparePayResultType.PaymentPossible) {
return (
<Fragment>

View File

@ -121,7 +121,7 @@ const transactionError = {
code: 2000,
details: "details",
hint: "this is a hint for the error",
message: "message",
message: "this is the error message with get from the app",
};
export const Withdraw = createExample(TestedComponent, {

View File

@ -29,7 +29,7 @@ import { route } from "preact-router";
import { useState } from "preact/hooks";
import emptyImg from "../../static/img/empty.png";
import { BankDetailsByPaytoType } from "../components/BankDetailsByPaytoType";
import { ErrorMessage } from "../components/ErrorMessage";
import { ErrorTalerOperation } from "../components/ErrorTalerOperation";
import { Part } from "../components/Part";
import {
Button,
@ -128,7 +128,10 @@ export function TransactionView({
return (
<Fragment>
<section style={{ padding: 8, textAlign: "center" }}>
<ErrorMessage title={transaction?.error?.hint} />
<ErrorTalerOperation
title="There was an error trying to complete the transaction"
error={transaction?.error}
/>
{transaction.pending && (
<WarningBox>This transaction is not completed</WarningBox>
)}