gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-wallet-core] 02/03: obs and cancel request, plus lint


From: gnunet
Subject: [taler-wallet-core] 02/03: obs and cancel request, plus lint
Date: Mon, 11 Mar 2024 18:58:06 +0100

This is an automated email from the git hooks/post-receive script.

sebasjm pushed a commit to branch master
in repository wallet-core.

commit 6e02a3852590f39cdd414a1caf89506bcd9dc83a
Author: Sebastian <sebasjm@gmail.com>
AuthorDate: Mon Mar 11 14:57:03 2024 -0300

    obs and cancel request, plus lint
---
 packages/web-util/src/components/Button.tsx        | 36 +++++++++---
 packages/web-util/src/components/CopyButton.tsx    |  5 +-
 packages/web-util/src/components/ErrorLoading.tsx  | 28 +++++++++
 packages/web-util/src/components/Header.tsx        | 39 +++++++++++--
 .../web-util/src/components/NotificationBanner.tsx |  4 +-
 packages/web-util/src/components/ToastBanner.tsx   | 59 ++++++++++++-------
 packages/web-util/src/hooks/useNotifications.ts    | 68 +++++++++++++++++-----
 packages/web-util/src/utils/http-impl.sw.ts        |  5 +-
 8 files changed, 191 insertions(+), 53 deletions(-)

diff --git a/packages/web-util/src/components/Button.tsx 
b/packages/web-util/src/components/Button.tsx
index 26b778eec..ea0ea2f38 100644
--- a/packages/web-util/src/components/Button.tsx
+++ b/packages/web-util/src/components/Button.tsx
@@ -1,8 +1,24 @@
-import { OperationFail, OperationOk, OperationResult, TalerError, 
TranslatedString } from "@gnu-taler/taler-util";
+/*
+ This file is part of GNU Taler
+ (C) 2022-2024 Taler Systems S.A.
+
+ 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 { AbsoluteTime, OperationFail, OperationOk, OperationResult, 
TalerError, TranslatedString } from "@gnu-taler/taler-util";
 // import { NotificationMessage, notifyInfo } from 
"@gnu-taler/web-util/browser";
 import { Fragment, VNode, h } from "preact";
 import { HTMLAttributes, useEffect, useState, useTransition } from 
"preact/compat";
-import { NotificationMessage, buildRequestErrorMessage, notifyInfo, 
useTranslationContext } from "../index.browser.js";
+import { NotificationMessage, buildUnifiedRequestErrorMessage, notifyInfo, 
useTranslationContext } from "../index.browser.js";
 // import { useBankCoreApiContext } from "../context/config.js";
 
 // function errorMap<T extends OperationFail<unknown>>(resp: T, map: (d: 
T["case"]) => TranslatedString): void {
@@ -10,7 +26,7 @@ import { NotificationMessage, buildRequestErrorMessage, 
notifyInfo, useTranslati
 export interface ButtonHandler<T extends OperationResult<A, B>, A, B> {
   onClick: () => Promise<T | undefined>,
   onNotification: (n: NotificationMessage) => void;
-  onOperationSuccess: ((result:T extends OperationOk<any> ? T :never) => void) 
| ((result:T extends OperationOk<any> ? T :never) => TranslatedString | 
undefined),
+  onOperationSuccess: ((result: T extends OperationOk<any> ? T : never) => 
void) | ((result: T extends OperationOk<any> ? T : never) => TranslatedString | 
undefined),
   onOperationFail: (d: T extends OperationFail<any> ? T : never) => 
TranslatedString;
   onOperationComplete?: () => void;
 }
@@ -33,10 +49,10 @@ export function Button<T extends OperationResult<A, B>, A, 
B>({
   handler,
   children,
   disabled,
-  onClick:clickEvent,
+  onClick: clickEvent,
   ...rest
 }: Props<T, A, B>): VNode {
-  const {i18n} = useTranslationContext();
+  const { i18n } = useTranslationContext();
   const [running, setRunning] = useState(false)
   return <button {...rest} disabled={disabled || running} onClick={(e) => {
     e.preventDefault();
@@ -62,6 +78,7 @@ export function Button<T extends OperationResult<A, B>, A, 
B>({
             type: "error",
             description: error.detail.hint as TranslatedString,
             debug: error.detail,
+            when: AbsoluteTime.now(),
           })
         }
       }
@@ -71,17 +88,18 @@ export function Button<T extends OperationResult<A, B>, A, 
B>({
       setRunning(false)
     }).catch(error => {
       console.error(error)
-      
+
       if (error instanceof TalerError) {
-        handler.onNotification(buildRequestErrorMessage(i18n, error))
+        handler.onNotification(buildUnifiedRequestErrorMessage(i18n, error))
       } else {
         const description = (error instanceof Error ?
           error.message : String(error)) as TranslatedString
-  
+
         handler.onNotification({
           title: i18n.str`Operation failed`,
           type: "error",
           description,
+          when: AbsoluteTime.now(),
         })
       }
 
@@ -95,7 +113,7 @@ export function Button<T extends OperationResult<A, B>, A, 
B>({
   </button>
 }
 
-function Wait():VNode {
+function Wait(): VNode {
   return <Fragment>
     <style>{`
       #l1 {          width: 120px;
diff --git a/packages/web-util/src/components/CopyButton.tsx 
b/packages/web-util/src/components/CopyButton.tsx
index e76447291..fd7f8b3b4 100644
--- a/packages/web-util/src/components/CopyButton.tsx
+++ b/packages/web-util/src/components/CopyButton.tsx
@@ -38,7 +38,10 @@ export function CopyButton({ class: clazz, getContent }: { 
class: string, getCon
 
   if (!copied) {
     return (
-      <button class={clazz} onClick={copyText} >
+      <button class={clazz} onClick={e => {
+        e.preventDefault()
+        copyText()
+      }} >
         <CopyIcon />
       </button>
     );
diff --git a/packages/web-util/src/components/ErrorLoading.tsx 
b/packages/web-util/src/components/ErrorLoading.tsx
index 02f2a3282..7089266b9 100644
--- a/packages/web-util/src/components/ErrorLoading.tsx
+++ b/packages/web-util/src/components/ErrorLoading.tsx
@@ -26,6 +26,34 @@ export function ErrorLoading({ error, showDetail }: { error: 
TalerError, showDet
     //////////////////
     // Every error that can be produce in a Http Request
     //////////////////
+    case TalerErrorCode.GENERIC_TIMEOUT: {
+      if (error.hasErrorCode(TalerErrorCode.GENERIC_TIMEOUT)) {
+        const { requestMethod, requestUrl, timeoutMs } = error.errorDetail
+        return <Attention type="danger" title={i18n.str`The request reached a 
timeout, check your connection.`}>
+          {error.message}
+          {showDetail &&
+            <pre class="whitespace-break-spaces ">
+              {JSON.stringify({ requestMethod, requestUrl, timeoutMs }, 
undefined, 2)}
+            </pre>
+          }
+        </Attention>
+      }
+      assertUnreachable(1 as never)
+    }
+    case TalerErrorCode.GENERIC_CLIENT_INTERNAL_ERROR: {
+      if (error.hasErrorCode(TalerErrorCode.GENERIC_CLIENT_INTERNAL_ERROR)) {
+        const { requestMethod, requestUrl, timeoutMs } = error.errorDetail
+        return <Attention type="danger" title={i18n.str`The request was 
cancelled.`}>
+          {error.message}
+          {showDetail &&
+            <pre class="whitespace-break-spaces ">
+              {JSON.stringify({ requestMethod, requestUrl, timeoutMs }, 
undefined, 2)}
+            </pre>
+          }
+        </Attention>
+      }
+      assertUnreachable(1 as never)
+    }
     case TalerErrorCode.WALLET_HTTP_REQUEST_GENERIC_TIMEOUT: {
       if 
(error.hasErrorCode(TalerErrorCode.WALLET_HTTP_REQUEST_GENERIC_TIMEOUT)) {
         const { requestMethod, requestUrl, timeoutMs } = error.errorDetail
diff --git a/packages/web-util/src/components/Header.tsx 
b/packages/web-util/src/components/Header.tsx
index fc7716320..29f4a4949 100644
--- a/packages/web-util/src/components/Header.tsx
+++ b/packages/web-util/src/components/Header.tsx
@@ -1,12 +1,24 @@
 import { useState } from "preact/hooks";
-import { LangSelector, useTranslationContext } from "../index.browser.js";
+import { LangSelector, useNotifications, useTranslationContext } from 
"../index.browser.js";
 import { ComponentChildren, Fragment, VNode, h } from "preact";
 import logo from "../assets/logo-2021.svg";
 
-export function Header({ title, profileURL, iconLinkURL, sites, onLogout, 
children }:
-  { title: string, iconLinkURL: string, profileURL?: string, children?: 
ComponentChildren, onLogout: (() => void) | undefined, sites: 
Array<Array<string>>, supportedLangs: string[] }): VNode {
+interface Props {
+  title: string;
+  iconLinkURL: string;
+  profileURL?: string;
+  notificationURL?: string;
+  children?: ComponentChildren;
+  onLogout: (() => void) | undefined;
+  sites: Array<Array<string>>;
+  supportedLangs: string[]
+}
+
+export function Header({ title, profileURL, notificationURL, iconLinkURL, 
sites, onLogout, children }: Props): VNode {
   const { i18n } = useTranslationContext();
   const [open, setOpen] = useState(false)
+  const ns = useNotifications();
+
   return <Fragment>
     <header class="bg-indigo-600 w-full mx-auto px-2 border-b 
border-opacity-25 border-indigo-400">
       <div class="flex flex-row h-16 items-center ">
@@ -35,6 +47,22 @@ export function Header({ title, profileURL, iconLinkURL, 
sites, onLogout, childr
           </div>
         </div>
         <div class="flex justify-end">
+          {!notificationURL ? undefined :
+            <a href={notificationURL} name="notifications" class="relative 
inline-flex items-center justify-center rounded-md bg-indigo-600 p-1 mr-2 
text-indigo-200 hover:bg-indigo-500 hover:bg-opacity-75 hover:text-white 
focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 
focus:ring-offset-indigo-600" aria-controls="mobile-menu" aria-expanded="false">
+              <span class="absolute -inset-0.5"></span>
+              <span class="sr-only"><i18n.Translate>Show 
notifications</i18n.Translate></span>
+              {ns.length > 0 ?
+                <svg xmlns="http://www.w3.org/2000/svg"; viewBox="0 0 24 24" 
fill="currentColor" class="w-10 h-10">
+                  <path d="M5.85 3.5a.75.75 0 0 0-1.117-1 9.719 9.719 0 0 
0-2.348 4.876.75.75 0 0 0 1.479.248A8.219 8.219 0 0 1 5.85 3.5ZM19.267 
2.5a.75.75 0 1 0-1.118 1 8.22 8.22 0 0 1 1.987 4.124.75.75 0 0 0 1.48-.248A9.72 
9.72 0 0 0 19.266 2.5Z" />
+                  <path fill-rule="evenodd" d="M12 2.25A6.75 6.75 0 0 0 5.25 
9v.75a8.217 8.217 0 0 1-2.119 5.52.75.75 0 0 0 .298 1.206c1.544.57 3.16.99 
4.831 1.243a3.75 3.75 0 1 0 7.48 0 24.583 24.583 0 0 0 4.83-1.244.75.75 0 0 0 
.298-1.205 8.217 8.217 0 0 1-2.118-5.52V9A6.75 6.75 0 0 0 12 2.25ZM9.75 
18c0-.034 0-.067.002-.1a25.05 25.05 0 0 0 4.496 0l.002.1a2.25 2.25 0 1 1-4.5 
0Z" clip-rule="evenodd" />
+                </svg>
+                :
+                <svg xmlns="http://www.w3.org/2000/svg"; fill="none" viewBox="0 
0 24 24" stroke-width="1.5" stroke="currentColor" class="w-10 h-10">
+                  <path stroke-linecap="round" stroke-linejoin="round" 
d="M14.857 17.082a23.848 23.848 0 0 0 5.454-1.31A8.967 8.967 0 0 1 18 9.75V9A6 
6 0 0 0 6 9v.75a8.967 8.967 0 0 1-2.312 6.022c1.733.64 3.56 1.085 5.455 
1.31m5.714 0a24.255 24.255 0 0 1-5.714 0m5.714 0a3 3 0 1 1-5.714 0" />
+                </svg>
+              }
+            </a>
+          }
           {!profileURL ? undefined :
             <a href={profileURL} name="profile" class="relative inline-flex 
items-center justify-center rounded-md bg-indigo-600 p-1 mr-2 text-indigo-200 
hover:bg-indigo-500 hover:bg-opacity-75 hover:text-white focus:outline-none 
focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-indigo-600" 
aria-controls="mobile-menu" aria-expanded="false">
               <span class="absolute -inset-0.5"></span>
@@ -58,7 +86,8 @@ export function Header({ title, profileURL, iconLinkURL, 
sites, onLogout, childr
       </div>
     </header>
 
-    {open &&
+    {
+      open &&
       <div class="relative z-10" name="sidebar overlay" 
aria-labelledby="slide-over-title" role="dialog" aria-modal="true"
         onClick={() => {
           setOpen(false)
@@ -150,5 +179,5 @@ export function Header({ title, profileURL, iconLinkURL, 
sites, onLogout, childr
         </div>
       </div>
     }
-  </Fragment>
+  </Fragment >
 }
diff --git a/packages/web-util/src/components/NotificationBanner.tsx 
b/packages/web-util/src/components/NotificationBanner.tsx
index 62733ab3c..31d5a5d01 100644
--- a/packages/web-util/src/components/NotificationBanner.tsx
+++ b/packages/web-util/src/components/NotificationBanner.tsx
@@ -9,7 +9,7 @@ export function LocalNotificationBanner({ notification, 
showDebug }: { notificat
       return <div class="relative">
         <div class="fixed top-0 left-0 right-0 z-20 w-full p-4">
           <Attention type="danger" title={notification.message.title} 
onClose={() => {
-            notification.remove()
+            notification.acknowledge()
           }}>
             {notification.message.description &&
               <div class="mt-2 text-sm text-red-700">
@@ -26,7 +26,7 @@ export function LocalNotificationBanner({ notification, 
showDebug }: { notificat
       return <div class="relative">
         <div class="fixed top-0 left-0 right-0 z-20 w-full p-4">
           <Attention type="success" title={notification.message.title} 
onClose={() => {
-            notification.remove();
+            notification.acknowledge();
           }} /></div></div>
   }
 }
diff --git a/packages/web-util/src/components/ToastBanner.tsx 
b/packages/web-util/src/components/ToastBanner.tsx
index 2424b17ff..ece26285f 100644
--- a/packages/web-util/src/components/ToastBanner.tsx
+++ b/packages/web-util/src/components/ToastBanner.tsx
@@ -1,5 +1,20 @@
+/*
+ This file is part of GNU Taler
+ (C) 2022-2024 Taler Systems S.A.
+
+ 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 { Fragment, VNode, h } from "preact"
-import { Attention, GLOBAL_NOTIFICATION_TIMEOUT as GLOBAL_TOAST_TIMEOUT, 
useNotifications } from "../index.browser.js"
+import { Attention, GLOBAL_NOTIFICATION_TIMEOUT as GLOBAL_TOAST_TIMEOUT, 
Notification, useNotifications } from "../index.browser.js"
 
 /**
  * Toasts should be considered when displaying these types of information to 
the user:
@@ -21,24 +36,26 @@ import { Attention, GLOBAL_NOTIFICATION_TIMEOUT as 
GLOBAL_TOAST_TIMEOUT, useNoti
 export function ToastBanner(): VNode {
   const notifs = useNotifications()
   if (notifs.length === 0) return <Fragment />
-  return <Fragment> {
-    notifs.map(n => {
-      switch (n.message.type) {
-        case "error":
-          return <Attention type="danger" title={n.message.title} onClose={() 
=> {
-            n.remove()
-          }} timeout={GLOBAL_TOAST_TIMEOUT}>
-            {n.message.description &&
-              <div class="mt-2 text-sm text-red-700">
-                {n.message.description}
-              </div>
-            }
-          </Attention>
-        case "info":
-          return <Attention type="success" title={n.message.title} onClose={() 
=> {
-            n.remove();
-          }} timeout={GLOBAL_TOAST_TIMEOUT} />
-      }
-    })}
-  </Fragment>
+  const show = notifs.filter(e => !e.message.ack && !e.message.timeout)
+  if (show.length === 0) return <Fragment />
+  return <AttentionByType msg={show[0]} />
+}
+
+function AttentionByType({ msg }: { msg: Notification }) {
+  switch (msg.message.type) {
+    case "error":
+      return <Attention type="danger" title={msg.message.title} onClose={() => 
{
+        msg.acknowledge()
+      }} timeout={GLOBAL_TOAST_TIMEOUT}>
+        {msg.message.description &&
+          <div class="mt-2 text-sm text-red-700">
+            {msg.message.description}
+          </div>
+        }
+      </Attention>
+    case "info":
+      return <Attention type="success" title={msg.message.title} onClose={() 
=> {
+        msg.acknowledge();
+      }} timeout={GLOBAL_TOAST_TIMEOUT} />
+  }
 }
diff --git a/packages/web-util/src/hooks/useNotifications.ts 
b/packages/web-util/src/hooks/useNotifications.ts
index 000abbc94..99f4f2699 100644
--- a/packages/web-util/src/hooks/useNotifications.ts
+++ b/packages/web-util/src/hooks/useNotifications.ts
@@ -1,4 +1,5 @@
 import {
+  AbsoluteTime,
   Duration,
   OperationFail,
   OperationOk,
@@ -20,12 +21,18 @@ export type NotificationMessage = ErrorNotification | 
InfoNotification;
 export interface ErrorNotification {
   type: "error";
   title: TranslatedString;
+  ack?: boolean;
+  timeout?: boolean;
   description?: TranslatedString;
   debug?: any;
+  when: AbsoluteTime;
 }
 export interface InfoNotification {
   type: "info";
   title: TranslatedString;
+  ack?: boolean;
+  timeout?: boolean;
+  when: AbsoluteTime;
 }
 
 const storage = memoryMap<Map<string, NotificationMessage>>();
@@ -35,11 +42,11 @@ export const GLOBAL_NOTIFICATION_TIMEOUT = 
Duration.fromSpec({
   seconds: 5,
 });
 
-function removeFromStorage(n: NotificationMessage) {
+function updateInStorage(n: NotificationMessage) {
   const h = hash(n);
   const mem = storage.get(NOTIFICATION_KEY) ?? new Map();
   const newState = new Map(mem);
-  newState.delete(h);
+  newState.set(h, n);
   storage.set(NOTIFICATION_KEY, newState);
 }
 
@@ -50,7 +57,8 @@ export function notify(notif: NotificationMessage): void {
 
   if (GLOBAL_NOTIFICATION_TIMEOUT.d_ms !== "forever") {
     setTimeout(() => {
-      removeFromStorage(notif);
+      notif.timeout = true;
+      updateInStorage(notif);
     }, GLOBAL_NOTIFICATION_TIMEOUT.d_ms);
   }
 
@@ -66,6 +74,7 @@ export function notifyError(
     title,
     description,
     debug,
+    when: AbsoluteTime.now(),
   });
 }
 export function notifyException(title: TranslatedString, ex: Error) {
@@ -74,34 +83,40 @@ export function notifyException(title: TranslatedString, 
ex: Error) {
     title,
     description: ex.message as TranslatedString,
     debug: ex.stack,
+    when: AbsoluteTime.now(),
   });
 }
 export function notifyInfo(title: TranslatedString) {
   notify({
     type: "info" as const,
     title,
+    when: AbsoluteTime.now(),
   });
 }
 
 export type Notification = {
   message: NotificationMessage;
-  remove: () => void;
+  acknowledge: () => void;
 };
 
 export function useNotifications(): Notification[] {
-  const [value, setter] = useState<Map<string, NotificationMessage>>(new 
Map());
+  const [, setLastUpdate] = useState<number>();
+  const value = storage.get(NOTIFICATION_KEY) ?? new Map();
+
   useEffect(() => {
     return storage.onUpdate(NOTIFICATION_KEY, () => {
-      const mem = storage.get(NOTIFICATION_KEY) ?? new Map();
-      setter(structuredClone(mem));
+      setLastUpdate(Date.now())
+      // const mem = storage.get(NOTIFICATION_KEY) ?? new Map();
+      // setter(structuredClone(mem));
     });
   });
 
   return Array.from(value.values()).map((message, idx) => {
     return {
       message,
-      remove: () => {
-        removeFromStorage(message);
+      acknowledge: () => {
+        message.ack = true;
+        updateInStorage(message);
       },
     };
   });
@@ -141,6 +156,7 @@ function errorMap<T extends OperationFail<unknown>>(
     title: map(resp.case),
     description: resp.detail.hint as TranslatedString,
     debug: resp.detail,
+    when: AbsoluteTime.now(),
   });
 }
 
@@ -165,7 +181,7 @@ export function useLocalNotification(): [
     ? undefined
     : {
       message: value,
-      remove: () => {
+      acknowledge: () => {
         setter(undefined);
       },
     };
@@ -175,7 +191,7 @@ export function useLocalNotification(): [
       return await cb(errorMap);
     } catch (error: unknown) {
       if (error instanceof TalerError) {
-        notify(buildRequestErrorMessage(i18n, error));
+        notify(buildUnifiedRequestErrorMessage(i18n, error));
       } else {
         notifyError(
           i18n.str`Operation failed, please report`,
@@ -212,7 +228,7 @@ export function useLocalNotificationHandler(): [
     ? undefined
     : {
       message: value,
-      remove: () => {
+      acknowledge: () => {
         setter(undefined);
       },
     };
@@ -241,18 +257,39 @@ export function useLocalNotificationHandler(): [
   return [notif, makeHandler, setter];
 }
 
-export function buildRequestErrorMessage(
+export function buildUnifiedRequestErrorMessage(
   i18n: InternationalizationAPI,
   cause: TalerError,
 ): ErrorNotification {
   let result: ErrorNotification;
   switch (cause.errorDetail.code) {
+    case TalerErrorCode.GENERIC_TIMEOUT: {
+      result = {
+        type: "error",
+        title: i18n.str`Request timeout`,
+        description: cause.message as TranslatedString,
+        debug: JSON.stringify(cause.errorDetail, undefined, 2),
+        when: AbsoluteTime.now(),
+      };
+      break;
+    }
+    case TalerErrorCode.GENERIC_CLIENT_INTERNAL_ERROR: {
+      result = {
+        type: "error",
+        title: i18n.str`Request cancelled`,
+        description: cause.message as TranslatedString,
+        debug: JSON.stringify(cause.errorDetail, undefined, 2),
+        when: AbsoluteTime.now(),
+      };
+      break;
+    }
     case TalerErrorCode.WALLET_HTTP_REQUEST_GENERIC_TIMEOUT: {
       result = {
         type: "error",
         title: i18n.str`Request timeout`,
         description: cause.message as TranslatedString,
         debug: JSON.stringify(cause.errorDetail, undefined, 2),
+        when: AbsoluteTime.now(),
       };
       break;
     }
@@ -262,6 +299,7 @@ export function buildRequestErrorMessage(
         title: i18n.str`Request throttled`,
         description: cause.message as TranslatedString,
         debug: JSON.stringify(cause.errorDetail, undefined, 2),
+        when: AbsoluteTime.now(),
       };
       break;
     }
@@ -271,6 +309,7 @@ export function buildRequestErrorMessage(
         title: i18n.str`Malformed response`,
         description: cause.message as TranslatedString,
         debug: JSON.stringify(cause.errorDetail, undefined, 2),
+        when: AbsoluteTime.now(),
       };
       break;
     }
@@ -280,6 +319,7 @@ export function buildRequestErrorMessage(
         title: i18n.str`Network error`,
         description: cause.message as TranslatedString,
         debug: JSON.stringify(cause.errorDetail, undefined, 2),
+        when: AbsoluteTime.now(),
       };
       break;
     }
@@ -289,6 +329,7 @@ export function buildRequestErrorMessage(
         title: i18n.str`Unexpected request error`,
         description: cause.message as TranslatedString,
         debug: JSON.stringify(cause.errorDetail, undefined, 2),
+        when: AbsoluteTime.now(),
       };
       break;
     }
@@ -298,6 +339,7 @@ export function buildRequestErrorMessage(
         title: i18n.str`Unexpected error`,
         description: cause.message as TranslatedString,
         debug: JSON.stringify(cause.errorDetail, undefined, 2),
+        when: AbsoluteTime.now(),
       };
       break;
     }
diff --git a/packages/web-util/src/utils/http-impl.sw.ts 
b/packages/web-util/src/utils/http-impl.sw.ts
index 316b75dfd..4d7f3a8a1 100644
--- a/packages/web-util/src/utils/http-impl.sw.ts
+++ b/packages/web-util/src/utils/http-impl.sw.ts
@@ -22,6 +22,7 @@ import {
   TalerErrorCode,
   TalerError,
   Duration,
+  CancellationToken,
 } from "@gnu-taler/taler-util";
 
 import {
@@ -137,13 +138,13 @@ export class BrowserFetchHttpLib implements 
HttpRequestLibrary {
     } catch (e) {
       if (controller.signal) {
         throw TalerError.fromDetail(
-          TalerErrorCode.WALLET_HTTP_REQUEST_GENERIC_TIMEOUT,
+          controller.signal.reason,
           {
             requestUrl,
             requestMethod,
             timeoutMs: requestTimeout.d_ms === "forever" ? 0 : 
requestTimeout.d_ms
           },
-          `request to ${requestUrl} timed out`,
+          `HTTP request failed.`,
         );
       }
       throw e;

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]