gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] [taler-wallet-webex] 01/02: add rudimentary error reporting


From: gnunet
Subject: [GNUnet-SVN] [taler-wallet-webex] 01/02: add rudimentary error reporting in a new tab
Date: Sun, 27 Aug 2017 03:56:31 +0200

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

dold pushed a commit to branch master
in repository wallet-webex.

commit 21c176a69ee04c4d59baedb79017f6c42ece22d6
Author: Florian Dold <address@hidden>
AuthorDate: Fri Aug 25 18:08:37 2017 +0200

    add rudimentary error reporting in a new tab
---
 src/logging.ts            | 45 +++++++++++++++++++++++++++++++--
 src/webex/messages.ts     |  8 ++++++
 src/webex/pages/error.tsx | 63 ++++++++++++++++++++++++++++++++++-------------
 src/webex/wxApi.ts        |  8 ++++++
 src/webex/wxBackend.ts    |  9 +++++++
 5 files changed, 114 insertions(+), 19 deletions(-)

diff --git a/src/logging.ts b/src/logging.ts
index a589c809..2c559e8d 100644
--- a/src/logging.ts
+++ b/src/logging.ts
@@ -208,6 +208,44 @@ export async function recordException(msg: string, e: 
any): Promise<void> {
   return record("error", e.toString(), stack, frame.file, frame.line, 
frame.column);
 }
 
+
+/**
+ * Cache for reports.  Also used when something is so broken that we can't even
+ * access the database.
+ */
+const reportCache: { [reportId: string]: any } = {};
+
+
+/**
+ * Get a UUID that does not use cryptographically secure randomness.
+ * Formatted as RFC4122 version 4 UUID.
+ */
+function getInsecureUuid() {
+  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
+    var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
+    return v.toString(16);
+  });
+}
+
+
+/**
+ * Store a report and return a unique identifier to retrieve it later.
+ */
+export async function storeReport(report: any): Promise<string> {
+  const uid = getInsecureUuid();
+  reportCache[uid] = report;
+  return uid;
+}
+
+
+/**
+ * Retrieve a report by its unique identifier.
+ */
+export async function getReport(reportUid: string): Promise<any> {
+  return reportCache[reportUid];
+}
+
+
 /**
  * Record a log entry in the database.
  */
@@ -218,6 +256,8 @@ export async function record(level: Level,
                              line?: number,
                              col?: number): Promise<void> {
   if (typeof indexedDB === "undefined") {
+    console.log("can't access DB for logging in this context");
+    console.log("log was", { level, msg, detail, source, line, col });
     return;
   }
 
@@ -257,7 +297,7 @@ export async function record(level: Level,
   }
 }
 
-const loggingDbVersion = 1;
+const loggingDbVersion = 2;
 
 const logsStore: Store<LogEntry> = new Store<LogEntry>("logs");
 
@@ -283,7 +323,8 @@ export function openLoggingDb(): Promise<IDBDatabase> {
           console.error(e);
         }
       }
-      resDb.createObjectStore("logs", {keyPath: "id", autoIncrement: true});
+      resDb.createObjectStore("logs", { keyPath: "id", autoIncrement: true });
+      resDb.createObjectStore("reports", { keyPath: "uid", autoIncrement: 
false });
     };
   });
 }
diff --git a/src/webex/messages.ts b/src/webex/messages.ts
index d7ecd06a..397e8876 100644
--- a/src/webex/messages.ts
+++ b/src/webex/messages.ts
@@ -176,6 +176,14 @@ export interface MessageMap {
     request: { };
     response: void;
   };
+  "log-and-display-error": {
+    request: any;
+    response: void;
+  };
+  "get-report": {
+    request: { reportUid: string };
+    response: void;
+  };
 }
 
 /**
diff --git a/src/webex/pages/error.tsx b/src/webex/pages/error.tsx
index e86b6cf4..3f3940d7 100644
--- a/src/webex/pages/error.tsx
+++ b/src/webex/pages/error.tsx
@@ -22,40 +22,69 @@
  * @author Florian Dold
  */
 
+
 import * as React from "react";
 import * as ReactDOM from "react-dom";
 import URI = require("urijs");
 
+import * as wxApi from "../wxApi";
+
 interface ErrorProps {
-  message: string;
+  report: any;
 }
 
 class ErrorView extends React.Component<ErrorProps, { }> {
   render(): JSX.Element {
-    return (
-      <div>
-        An error occurred: {this.props.message}
-      </div>
-    );
+    const report = this.props.report;
+    if (!report) {
+      return (
+        <div>
+          <h1>Error Report Not Found</h1>
+          <p>This page is supposed to display an error reported by the GNU 
Taler wallet,
+              but the corresponding error report can't be found.</p>
+          <p>Maybe the error occured before the browser was restarted or the 
wallet was reloaded.</p>
+        </div>
+      );
+    }
+    switch (report.name) {
+      default:
+        return (
+          <div>
+            <h1>Unknown Error</h1>
+            The GNU Taler wallet reported an unknown error.  Here are the 
details:
+            <pre>
+              {JSON.stringify(report, null, " ")}
+            </pre>
+          </div>
+        );
+    }
   }
 }
 
 async function main() {
-  try {
-    const url = new URI(document.location.href);
-    const query: any = URI.parseQuery(url.query());
+  const url = new URI(document.location.href);
+  const query: any = URI.parseQuery(url.query());
 
-    const message: string = query.message || "unknown error";
+  const container = document.getElementById("container");
+  if (!container) {
+    console.error("fatal: can't mount component, countainer missing");
+    return;
+  }
 
-    ReactDOM.render(<ErrorView message={message} />, document.getElementById(
-      "container")!);
+  // report that we'll render, either looked up from the
+  // logging module or synthesized here for fixed/fatal errors
+  let report;
 
-  } catch (e) {
-    // TODO: provide more context information, maybe factor it out into a
-    // TODO:generic error reporting function or component.
-    document.body.innerText = `Fatal error: "${e.message}".`;
-    console.error(`got error "${e.message}"`, e);
+  const reportUid: string = query.reportUid;
+  if (!reportUid) {
+    report = {
+      name: "missing-error",
+    };
+  } else {
+    report = await wxApi.getReport(reportUid);
   }
+
+  ReactDOM.render(<ErrorView report={report} />, container);
 }
 
 document.addEventListener("DOMContentLoaded", () => main());
diff --git a/src/webex/wxApi.ts b/src/webex/wxApi.ts
index 1371e27e..306406a1 100644
--- a/src/webex/wxApi.ts
+++ b/src/webex/wxApi.ts
@@ -321,3 +321,11 @@ export function getSenderWireInfos(): 
Promise<SenderWireInfos> {
 export function returnCoins(args: { amount: AmountJson, exchange: string, 
senderWire: object }): Promise<void> {
   return callBackend("return-coins", args);
 }
+
+export function logAndDisplayError(args: any): Promise<void> {
+  return callBackend("log-and-display-error", args);
+}
+
+export function getReport(reportUid: string): Promise<void> {
+  return callBackend("get-report", { reportUid });
+}
diff --git a/src/webex/wxBackend.ts b/src/webex/wxBackend.ts
index 974bcb3c..353961ff 100644
--- a/src/webex/wxBackend.ts
+++ b/src/webex/wxBackend.ts
@@ -303,6 +303,15 @@ function handleMessage(sender: MessageSender,
       }
       return resp;
     }
+    case "log-and-display-error":
+      logging.storeReport(detail).then((reportUid) => {
+        chrome.tabs.create({
+          url: 
chrome.extension.getURL(`/src/webex/pages/error.html?reportUid=${reportUid}`),
+        });
+      });
+      return;
+    case "get-report":
+      return logging.getReport(detail.reportUid);
     default:
       // Exhaustiveness check.
       // See https://www.typescriptlang.org/docs/handbook/advanced-types.html

-- 
To stop receiving notification emails like this one, please contact
address@hidden



reply via email to

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