Show an error message on upload failed
authorCyperghost <olaf_schmitz_1@t-online.de>
Tue, 18 Jun 2024 10:12:00 +0000 (12:12 +0200)
committerCyperghost <olaf_schmitz_1@t-online.de>
Tue, 18 Jun 2024 10:12:00 +0000 (12:12 +0200)
ts/WoltLabSuite/Core/Form/Builder/Field/Controller/FileProcessor.ts
wcfsetup/install/files/js/WoltLabSuite/Core/Form/Builder/Field/Controller/FileProcessor.js

index e7b0cdafc7d88fc9e4b765404f62d4402499305c..b1113cfd4e9eacaf3f36194ea97213e842cac576 100644 (file)
@@ -37,10 +37,15 @@ export class FileProcessor {
   }
 
   async #registerFile(element: WoltlabCoreFileElement): Promise<void> {
-    let elementContainer: HTMLElement;
+    let elementContainer: HTMLElement | null;
 
     if (this.isSingleFileUpload) {
-      elementContainer = this.#container.querySelector(".fileUpload__preview")!;
+      elementContainer = this.#container.querySelector(".fileUpload__preview");
+      if (elementContainer === null) {
+        elementContainer = document.createElement("div");
+        elementContainer.classList.add("fileUpload__preview");
+        this.#uploadButton.insertAdjacentElement("beforebegin", elementContainer);
+      }
     } else {
       elementContainer = document.createElement("li");
       elementContainer.classList.add("fileUpload__fileList__item");
@@ -56,14 +61,14 @@ export class FileProcessor {
         await deleteFile(this.#replaceElement.fileId!);
         this.#replaceElement = undefined;
       }
-    } catch (e) {
+    } catch (reason) {
       // reinsert the element and show an error message
       if (this.#replaceElement !== undefined) {
-        // TODO show an error message
         await this.#registerFile(this.#replaceElement);
         this.#replaceElement = undefined;
-        return;
       }
+      this.#markElementUploadHasFailed(elementContainer, element, reason);
+      return;
     }
 
     if (this.isSingleFileUpload) {
@@ -80,6 +85,39 @@ export class FileProcessor {
     this.#addButtons(element);
   }
 
+  #markElementUploadHasFailed(container: HTMLElement, element: WoltlabCoreFileElement, reason: unknown): void {
+    if (reason instanceof Error) {
+      throw reason;
+    }
+    if (element.apiError === undefined) {
+      return;
+    }
+    let errorMessage: string;
+
+    const validationError = element.apiError.getValidationError();
+    if (validationError !== undefined) {
+      switch (validationError.param) {
+        case "preflight":
+          errorMessage = getPhrase(`wcf.upload.error.${validationError.code}`);
+          break;
+
+        default:
+          errorMessage = "Unrecognized error type: " + JSON.stringify(validationError);
+          break;
+      }
+    } else {
+      errorMessage = `Unexpected server error: [${element.apiError.type}] ${element.apiError.message}`;
+    }
+
+    container.classList.add("innerError");
+
+    const errorElement = document.createElement("div");
+    errorElement.classList.add("fileUpload__fileList__item__errorMessage");
+    errorElement.textContent = errorMessage;
+
+    element.append(errorElement);
+  }
+
   #addButtons(element: WoltlabCoreFileElement): void {
     const buttons = document.createElement("ul");
     buttons.classList.add("buttonList");
index 2bfbbc0e653e09bffa4056187d5355202690b66b..0bec3cb7bcc197d9fdbfc3f08501edfbc60a623a 100644 (file)
@@ -34,6 +34,11 @@ define(["require", "exports", "WoltLabSuite/Core/Language", "WoltLabSuite/Core/A
             let elementContainer;
             if (this.isSingleFileUpload) {
                 elementContainer = this.#container.querySelector(".fileUpload__preview");
+                if (elementContainer === null) {
+                    elementContainer = document.createElement("div");
+                    elementContainer.classList.add("fileUpload__preview");
+                    this.#uploadButton.insertAdjacentElement("beforebegin", elementContainer);
+                }
             }
             else {
                 elementContainer = document.createElement("li");
@@ -48,14 +53,14 @@ define(["require", "exports", "WoltLabSuite/Core/Language", "WoltLabSuite/Core/A
                     this.#replaceElement = undefined;
                 }
             }
-            catch (e) {
+            catch (reason) {
                 // reinsert the element and show an error message
                 if (this.#replaceElement !== undefined) {
-                    // TODO show an error message
                     await this.#registerFile(this.#replaceElement);
                     this.#replaceElement = undefined;
-                    return;
                 }
+                this.#markElementUploadHasFailed(elementContainer, element, reason);
+                return;
             }
             if (this.isSingleFileUpload) {
                 element.dataset.previewUrl = element.link;
@@ -68,6 +73,34 @@ define(["require", "exports", "WoltLabSuite/Core/Language", "WoltLabSuite/Core/A
             elementContainer.append(input);
             this.#addButtons(element);
         }
+        #markElementUploadHasFailed(container, element, reason) {
+            if (reason instanceof Error) {
+                throw reason;
+            }
+            if (element.apiError === undefined) {
+                return;
+            }
+            let errorMessage;
+            const validationError = element.apiError.getValidationError();
+            if (validationError !== undefined) {
+                switch (validationError.param) {
+                    case "preflight":
+                        errorMessage = (0, Language_1.getPhrase)(`wcf.upload.error.${validationError.code}`);
+                        break;
+                    default:
+                        errorMessage = "Unrecognized error type: " + JSON.stringify(validationError);
+                        break;
+                }
+            }
+            else {
+                errorMessage = `Unexpected server error: [${element.apiError.type}] ${element.apiError.message}`;
+            }
+            container.classList.add("innerError");
+            const errorElement = document.createElement("div");
+            errorElement.classList.add("fileUpload__fileList__item__errorMessage");
+            errorElement.textContent = errorMessage;
+            element.append(errorElement);
+        }
         #addButtons(element) {
             const buttons = document.createElement("ul");
             buttons.classList.add("buttonList");