@@ -137,11 +137,11 @@ export default Vue.extend({
137137 computed: {
138138 ... mapGetters (' k8sManager' , {isK8sReady: ' isReady' }),
139139 volumeName() {
140- const name = this .$route .params .name ;
141- if ( ! name || ! / ^ [ a-zA-Z0-9 . _-] + $ / . test ( name )) {
142- throw new Error ( ' Invalid volume name format ' );
143- }
144- return name ;
140+ return this .$route .params .name || ' ' ;
141+ },
142+ isValidVolumeName() {
143+ const name = this . volumeName ;
144+ return name && / ^ [ a-zA-Z0-9 . _-] + $ / . test ( name ) ;
145145 },
146146 hasNamespaceSelected() {
147147 return this .settings ?.containerEngine ?.name === ContainerEngine .CONTAINERD && this .settings ?.containers ?.namespace ;
@@ -154,20 +154,29 @@ export default Vue.extend({
154154 },
155155 watch: {
156156 ' $route.query.path' : {
157- handler(newPath ) {
157+ async handler(newPath ) {
158158 const path = newPath || ' /' ;
159159 if (this .currentPath !== path ) {
160160 this .currentPath = path ;
161161 if (this .ddClient && this .volumeExists ) {
162162 this .isLoading = true ;
163- this .listFiles ();
163+ try {
164+ await this .listFiles ();
165+ } catch (error ) {
166+ console .error (' Error in path watcher:' , error );
167+ }
164168 }
165169 }
166170 },
167171 immediate: false
168172 }
169173 },
170174 mounted() {
175+ if (! this .isValidVolumeName ) {
176+ this .error = this .t (' volumes.files.invalidVolumeName' , {name: this .volumeName });
177+ return ;
178+ }
179+
171180 this .$store .dispatch (' page/setHeader' , {
172181 title: this .t (' volumes.files.title' ),
173182 description: this .volumeName ,
@@ -246,23 +255,28 @@ export default Vue.extend({
246255 );
247256
248257 // Only treat stderr as an error if it's not a warning or pull progress
249- if (stderr &&
250- ! stderr .includes (' level=warning' ) &&
251- ! stderr .includes (' Pulling from' ) &&
252- ! stderr .includes (' Pull complete' ) &&
253- ! stderr .includes (' Downloaded' ) &&
254- ! stderr .includes (' Downloading' ) &&
255- ! stderr .includes (' Waiting' ) &&
256- ! stderr .includes (' Verifying' ) &&
257- ! stderr .includes (' Extracting' )) {
258+ const nonErrorPatterns = [
259+ ' level=warning' , ' Pulling from' , ' Pull complete' ,
260+ ' Downloaded' , ' Downloading' , ' Waiting' , ' Verifying' , ' Extracting'
261+ ];
262+ const isRealError = stderr && ! nonErrorPatterns .some (pattern => stderr .includes (pattern ));
263+ if (isRealError ) {
258264 throw new Error (stderr );
259265 }
260266
261267 this .files = this .parseLsOutput (stdout );
262268 this .isLoading = false ;
263269 } catch (error ) {
270+ const errorSources = [
271+ error ?.message ,
272+ error ?.stderr ,
273+ error ?.error ,
274+ typeof error === ' string' ? error : null ,
275+ ' Failed to list files'
276+ ];
277+
264278 console .error (' Error listing files:' , error );
265- this .error = this .t (' volumes.files.listError' , {error: error . message });
279+ this .error = this .t (' volumes.files.listError' , {error: errorSources . find ( msg => msg ) });
266280 this .isLoading = false ;
267281 }
268282 },
@@ -330,31 +344,7 @@ export default Vue.extend({
330344 return ' icon icon-folder' ;
331345 }
332346
333- const ext = file .name .split (' .' ).pop ().toLowerCase ();
334- const iconMap = {
335- txt: ' icon-file-text' ,
336- log: ' icon-file-text' ,
337- json: ' icon-file-code' ,
338- yaml: ' icon-file-code' ,
339- yml: ' icon-file-code' ,
340- xml: ' icon-file-code' ,
341- html: ' icon-file-code' ,
342- js: ' icon-file-code' ,
343- ts: ' icon-file-code' ,
344- css: ' icon-file-code' ,
345- sh: ' icon-terminal' ,
346- bash: ' icon-terminal' ,
347- zip: ' icon-file-zip' ,
348- tar: ' icon-file-zip' ,
349- gz: ' icon-file-zip' ,
350- jpg: ' icon-image' ,
351- jpeg: ' icon-image' ,
352- png: ' icon-image' ,
353- gif: ' icon-image' ,
354- svg: ' icon-image' ,
355- };
356-
357- return ` icon ${iconMap [ext ] || ' icon-file' } ` ;
347+ return ' icon icon-file' ;
358348 },
359349 formatSize(bytes ) {
360350 if (bytes === 0 ) return ' 0 B' ;
0 commit comments