From 02485dd03804e3d1743daa4b1097917e7a375d29 Mon Sep 17 00:00:00 2001
From: Jason McCollum <jason.mccollum@woolpert.com>
Date: Wed, 7 Feb 2024 13:42:34 -0800
Subject: [PATCH] Improve zip error messaging

---
 .../upload-dialog.component.html              |  8 +++---
 .../upload-dialog/upload-dialog.component.ts  | 25 +++++++++++++++++++
 2 files changed, 29 insertions(+), 4 deletions(-)

diff --git a/application/frontend/src/app/core/containers/upload-dialog/upload-dialog.component.html b/application/frontend/src/app/core/containers/upload-dialog/upload-dialog.component.html
index 13b4ed38..20c0a9cf 100644
--- a/application/frontend/src/app/core/containers/upload-dialog/upload-dialog.component.html
+++ b/application/frontend/src/app/core/containers/upload-dialog/upload-dialog.component.html
@@ -62,16 +62,16 @@ <h4 class="strong d-flex mb-2">
             *ngIf="
               fileName.errors?.required && fileName.touched && fileName.dirty && !validatingUpload
             ">
-            File is required
+            File is required.
           </mat-error>
           <mat-error *ngIf="fileName.errors?.zipContents && (fileName.touched || fileName.dirty)">
-            Invalid zip contents
+            {{ getZipErrorMessage() }}
           </mat-error>
           <mat-error *ngIf="fileName.errors?.fileFormat && (fileName.touched || fileName.dirty)">
-            Invalid file format
+            The provided file cannot be loaded. Only valid .json and .zip files are supported.
           </mat-error>
           <mat-error *ngIf="fileName.errors?.requestFormat && (fileName.touched || fileName.dirty)">
-            The provided scenario is not valid
+            The provided scenario is not valid.
           </mat-error>
           <mat-hint>.json or .zip</mat-hint>
         </mat-form-field>
diff --git a/application/frontend/src/app/core/containers/upload-dialog/upload-dialog.component.ts b/application/frontend/src/app/core/containers/upload-dialog/upload-dialog.component.ts
index a88ae2ce..a1161381 100644
--- a/application/frontend/src/app/core/containers/upload-dialog/upload-dialog.component.ts
+++ b/application/frontend/src/app/core/containers/upload-dialog/upload-dialog.component.ts
@@ -72,6 +72,9 @@ export class UploadDialogComponent {
   }
   private scenarioSolutionPair: ScenarioSolutionPair;
   zipContentsInvalid: boolean;
+  zipContentCountInvalid: boolean;
+  zipMissingScenario: boolean;
+  zipMissingSolution: boolean;
 
   resolvingPlaceIds = false;
   placeIdProgress = 0;
@@ -300,7 +303,12 @@ export class UploadDialogComponent {
   }
 
   loadZipContents(files: { content: JSON; filename: string }[]): ScenarioSolutionPair {
+    this.zipContentCountInvalid = false;
+    this.zipMissingScenario = false;
+    this.zipMissingSolution = false;
+
     if (files.length !== 2) {
+      this.zipContentCountInvalid = true;
       throw new Error('Incorrect number of files');
     }
 
@@ -316,16 +324,33 @@ export class UploadDialogComponent {
     });
 
     if (!scenario) {
+      this.zipMissingScenario = true;
       throw new Error('Missing scenario.json');
     }
 
     if (!solution) {
+      this.zipMissingSolution = true;
       throw new Error('Missing solution.json');
     }
 
     return { scenario, solution };
   }
 
+  getZipErrorMessage(): string {
+    if (this.zipContentCountInvalid) {
+      return 'The zip contains an invalid number of .json files, or the .json files within are invalid.';
+    }
+    if (this.zipMissingScenario) {
+      return 'The provided zip is missing a valid scenario file.';
+    }
+
+    if (this.zipMissingSolution) {
+      return 'The provided zip is missing a valid solution file.';
+    }
+
+    return 'The provided zip contains invalid contents.';
+  }
+
   /**
    * Returns scenario validation errors
    *