aboutsummaryrefslogtreecommitdiff
path: root/packages/taler-wallet-webextension/src/context/alert.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/taler-wallet-webextension/src/context/alert.ts')
-rw-r--r--packages/taler-wallet-webextension/src/context/alert.ts98
1 files changed, 80 insertions, 18 deletions
diff --git a/packages/taler-wallet-webextension/src/context/alert.ts b/packages/taler-wallet-webextension/src/context/alert.ts
index cc98ec1e0..e67d94671 100644
--- a/packages/taler-wallet-webextension/src/context/alert.ts
+++ b/packages/taler-wallet-webextension/src/context/alert.ts
@@ -19,19 +19,26 @@
* @author Sebastian Javier Marchano (sebasjm)
*/
-import { TranslatedString } from "@gnu-taler/taler-util";
+import { TalerErrorDetail, TranslatedString } from "@gnu-taler/taler-util";
import { ComponentChildren, createContext, h, VNode } from "preact";
import { useContext, useState } from "preact/hooks";
+import { HookError } from "../hooks/useAsyncAsHook.js";
+import { SafeHandler, withSafe } from "../mui/handlers.js";
+import { BackgroundError } from "../wxApi.js";
export type AlertType = "info" | "warning" | "error" | "success";
-export interface Alert {
+export interface InfoAlert {
message: TranslatedString;
description: TranslatedString | VNode;
- type: AlertType;
+ type: "info" | "warning" | "success";
}
-export interface ErrorAlert extends Alert {
+export type Alert = InfoAlert | ErrorAlert;
+
+export interface ErrorAlert {
+ message: TranslatedString;
+ description: TranslatedString | VNode;
type: "error";
context: object;
cause: any;
@@ -41,10 +48,14 @@ type Type = {
alerts: Alert[];
pushAlert: (n: Alert) => void;
removeAlert: (n: Alert) => void;
+ pushAlertOnError: <T>(h: (p: T) => Promise<void>) => SafeHandler<T>;
};
const initial: Type = {
alerts: [],
+ pushAlertOnError: () => {
+ throw Error("alert context not initialized");
+ },
pushAlert: () => {
null;
},
@@ -80,8 +91,17 @@ export const AlertProvider = ({ children }: Props): VNode => {
setAlerts((ns: AlertWithDate[]) => ns.filter((n) => n !== alert));
};
+ function pushAlertOnError<T>(
+ handler: (p: T) => Promise<void>,
+ ): SafeHandler<T> {
+ return withSafe(handler, (e) => {
+ const a = alertFromError(e.message as TranslatedString, e);
+ pushAlert(a);
+ });
+ }
+
return h(Context.Provider, {
- value: { alerts, pushAlert, removeAlert },
+ value: { alerts, pushAlert, removeAlert, pushAlertOnError },
children,
});
};
@@ -90,29 +110,71 @@ export const useAlertContext = (): Type => useContext(Context);
export function alertFromError(
message: TranslatedString,
- error: unknown,
+ error: HookError,
...context: any[]
-): ErrorAlert {
- let description = "" as TranslatedString;
+): ErrorAlert;
- const isObject = typeof error === "object" &&
- error !== null;
- const hasMessage =
- isObject &&
- "message" in error &&
- typeof error.message === "string";
+export function alertFromError(
+ message: TranslatedString,
+ error: Error,
+ ...context: any[]
+): ErrorAlert;
- if (hasMessage) {
- description = error.message as TranslatedString;
+export function alertFromError(
+ message: TranslatedString,
+ error: TalerErrorDetail,
+ ...context: any[]
+): ErrorAlert;
+
+export function alertFromError(
+ message: TranslatedString,
+ error: HookError | TalerErrorDetail | Error,
+ ...context: any[]
+): ErrorAlert {
+ let description: TranslatedString;
+ let cause: any;
+
+ if (typeof error === "object" && error !== null) {
+ if ("code" in error) {
+ //TalerErrorDetail
+ description = (error.hint ??
+ `Error code: ${error.code}`) as TranslatedString;
+ cause = {
+ details: error,
+ };
+ } else if ("hasError" in error) {
+ //HookError
+ description = error.message as TranslatedString;
+ if (error.type === "taler") {
+ cause = {
+ details: error.details,
+ };
+ }
+ } else {
+ if (error instanceof BackgroundError) {
+ description = (error.errorDetail.hint ??
+ `Error code: ${error.errorDetail.code}`) as TranslatedString;
+ cause = {
+ details: error.errorDetail,
+ stack: error.stack,
+ };
+ } else {
+ description = error.message as TranslatedString;
+ cause = {
+ stack: error.stack,
+ };
+ }
+ }
} else {
- description = `Unknown error: ${String(error)}` as TranslatedString;
+ description = "" as TranslatedString;
+ cause = error;
}
return {
type: "error",
message,
description,
- cause: error,
+ cause,
context,
};
}