User-friendly messages for network errors
authorAlexander Ebert <ebert@woltlab.com>
Mon, 25 Apr 2022 14:49:53 +0000 (16:49 +0200)
committerAlexander Ebert <ebert@woltlab.com>
Mon, 25 Apr 2022 14:49:53 +0000 (16:49 +0200)
See https://www.woltlab.com/community/thread/295356-load-failed-wenn-keine-netzwerkverbindung-beim-klick-auf-die-benachrichtigungen/

com.woltlab.wcf/templates/headIncludeJavaScript.tpl
ts/WoltLabSuite/Core/Ajax/Error.ts
wcfsetup/install/files/js/WoltLabSuite/Core/Ajax/Error.js
wcfsetup/install/lang/de.xml
wcfsetup/install/lang/en.xml

index 4ce78187cb5970cad2cc915cf51f1e0f7a4f93e1..1784497c07d579c40ed6da59342b19d8c1632093 100644 (file)
@@ -94,6 +94,7 @@ window.addEventListener('pageshow', function(event) {
                        'wcf.global.confirmation.confirm': '{jslang}wcf.global.confirmation.confirm{/jslang}',
                        'wcf.global.confirmation.title': '{jslang}wcf.global.confirmation.title{/jslang}',
                        'wcf.global.decimalPoint': '{jslang}wcf.global.decimalPoint{/jslang}',
+                       'wcf.global.error.ajax.network': '{jslang __literal=true}wcf.global.error.ajax.network{/jslang}',
                        'wcf.global.error.timeout': '{jslang}wcf.global.error.timeout{/jslang}',
                        'wcf.global.form.error.empty': '{jslang}wcf.global.form.error.empty{/jslang}',
                        'wcf.global.form.error.greaterThan': '{jslang __literal=true}wcf.global.form.error.greaterThan{/jslang}',
index f0635327709d7af732707780aee4f004e0b7bb8d..1e026dcb27d97f1cd60667b35bf27e94deaefeec 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 import * as Core from "../Core";
+import * as Language from "../Language";
 
 type ErrorResponsePrevious = {
   message: string;
@@ -48,7 +49,12 @@ async function getErrorHtml(error: ApiError): Promise<string> {
   let message = "";
 
   if (error instanceof ConnectionError) {
-    message = error.message;
+    // `fetch()` will yield a `TypeError` for network errors and CORS violations.
+    if (error.originalError instanceof TypeError) {
+      message = Language.get("wcf.global.error.ajax.network", { message: error.message });
+    } else {
+      message = error.message;
+    }
   } else {
     if (error instanceof InvalidJson) {
       message = await error.response.clone().text();
index 6a9bef34c3fe8b518819214ede1ff8a7b9d05f36..501b447255407badcf8b8d7df32bc1259543c409 100644 (file)
@@ -7,11 +7,12 @@
  * @module WoltLabSuite/Core/Ajax/Error
  * @since 5.5
  */
-define(["require", "exports", "tslib", "../Core"], function (require, exports, tslib_1, Core) {
+define(["require", "exports", "tslib", "../Core", "../Language"], function (require, exports, tslib_1, Core, Language) {
     "use strict";
     Object.defineProperty(exports, "__esModule", { value: true });
     exports.registerGlobalRejectionHandler = exports.InvalidJson = exports.ExpectedJson = exports.StatusNotOk = exports.ConnectionError = exports.ApiError = void 0;
     Core = tslib_1.__importStar(Core);
+    Language = tslib_1.__importStar(Language);
     async function genericError(error) {
         const html = await getErrorHtml(error);
         if (html !== "") {
@@ -30,7 +31,13 @@ define(["require", "exports", "tslib", "../Core"], function (require, exports, t
         let details = "";
         let message = "";
         if (error instanceof ConnectionError) {
-            message = error.message;
+            // `fetch()` will yield a `TypeError` for network errors and CORS violations.
+            if (error.originalError instanceof TypeError) {
+                message = Language.get("wcf.global.error.ajax.network", { message: error.message });
+            }
+            else {
+                message = error.message;
+            }
         }
         else {
             if (error instanceof InvalidJson) {
index e9ca50ce9328f6d24c72345d8ea9a2a6efcff5b9..9d672d6c078e5b2af8638d2185c07a81e6f9fd9f 100644 (file)
@@ -3929,6 +3929,7 @@ Dateianhänge:
                <item name="wcf.global.date"><![CDATA[Datum]]></item>
                <item name="wcf.global.decimalPoint"><![CDATA[,]]></item>
                <item name="wcf.global.description"><![CDATA[Beschreibung]]></item>
+               <item name="wcf.global.error.ajax.network"><![CDATA[<p>Ein Verbindungsaufbau zum Server war nicht möglich, bitte überprüfen Sie Ihre Internetverbindung.</p><p><br></p><p>Fehlermeldung von Ihrem Browser: „{$message}“</p>]]></item>
                <item name="wcf.global.error.timeout"><![CDATA[Keine Antwort vom Server erhalten, Anfrage wurde abgebrochen.]]></item>
                <item name="wcf.global.error.title"><![CDATA[Fehlermeldung]]></item>
                <item name="wcf.global.exception.explanation"><![CDATA[<p class="exceptionSubtitle">Was ist passiert?</p>
index 9367d35d83a716f6e642bd8014c525c9b6b524b4..d40e774a625879f97d1b2a0261fa7e9d2dce9285 100644 (file)
@@ -3877,6 +3877,7 @@ Attachments:
                <item name="wcf.global.date"><![CDATA[Date]]></item>
                <item name="wcf.global.decimalPoint"><![CDATA[.]]></item>
                <item name="wcf.global.description"><![CDATA[Description]]></item>
+               <item name="wcf.global.error.ajax.network"><![CDATA[<p>Unable to connect to the server, please check your internet connection.</p><p><br></p><p>Error message from your browser: “{$message}”</p>]]></item>
                <item name="wcf.global.error.timeout"><![CDATA[Did not receive a response from server, request aborted.]]></item>
                <item name="wcf.global.error.title"><![CDATA[Error Message]]></item>
                <item name="wcf.global.exception.explanation"><![CDATA[<p class="exceptionSubtitle">What happened?</p>