Skip to content

Commit 4470dd6

Browse files
committed
fix(files): failsafe when executing actions methods
Signed-off-by: skjnldsv <[email protected]>
1 parent 3baa91d commit 4470dd6

File tree

2 files changed

+48
-16
lines changed

2 files changed

+48
-16
lines changed

apps/files/src/components/FileEntry/FileEntryActions.vue

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,14 @@ export default defineComponent({
163163
if (this.filesListWidth < 768 || this.gridMode) {
164164
return []
165165
}
166-
return this.enabledFileActions.filter(action => action?.inline?.(this.source, this.currentView))
166+
return this.enabledFileActions.filter(action => {
167+
try {
168+
return action?.inline?.(this.source, this.currentView)
169+
} catch (error) {
170+
logger.error('Error while checking if action is inline', { action, error })
171+
return false
172+
}
173+
})
167174
},
168175
169176
// Enabled action that are displayed inline with a custom render function
@@ -236,13 +243,19 @@ export default defineComponent({
236243
237244
methods: {
238245
actionDisplayName(action: FileAction) {
239-
if ((this.gridMode || (this.filesListWidth < 768 && action.inline)) && typeof action.title === 'function') {
240-
// if an inline action is rendered in the menu for
241-
// lack of space we use the title first if defined
242-
const title = action.title([this.source], this.currentView)
243-
if (title) return title
246+
try {
247+
if ((this.gridMode || (this.filesListWidth < 768 && action.inline)) && typeof action.title === 'function') {
248+
// if an inline action is rendered in the menu for
249+
// lack of space we use the title first if defined
250+
const title = action.title([this.source], this.currentView)
251+
if (title) return title
252+
}
253+
return action.displayName([this.source], this.currentView)
254+
} catch (error) {
255+
logger.error('Error while getting action display name', { action, error })
256+
// Not ideal, but better than nothing
257+
return action.id
244258
}
245-
return action.displayName([this.source], this.currentView)
246259
},
247260
248261
async onActionClick(action, isSubmenu = false) {
@@ -257,7 +270,13 @@ export default defineComponent({
257270
return
258271
}
259272
260-
const displayName = action.displayName([this.source], this.currentView)
273+
let displayName = action.id
274+
try {
275+
displayName = action.displayName([this.source], this.currentView)
276+
} catch (error) {
277+
logger.error('Error while getting action display name', { action, error })
278+
}
279+
261280
try {
262281
// Set the loading marker
263282
this.$emit('update:loading', action.id)
@@ -275,8 +294,8 @@ export default defineComponent({
275294
return
276295
}
277296
showError(t('files', '"{displayName}" action failed', { displayName }))
278-
} catch (e) {
279-
logger.error('Error while executing action', { action, e })
297+
} catch (error) {
298+
logger.error('Error while executing action', { action, error })
280299
showError(t('files', '"{displayName}" action failed', { displayName }))
281300
} finally {
282301
// Reset the loading marker

apps/files/src/components/FileEntryMixin.ts

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,21 @@
66
import type { PropType } from 'vue'
77
import type { FileSource } from '../types.ts'
88

9-
import { showError } from '@nextcloud/dialogs'
9+
import { extname } from 'path'
1010
import { FileType, Permission, Folder, File as NcFile, NodeStatus, Node, getFileActions } from '@nextcloud/files'
11-
import { translate as t } from '@nextcloud/l10n'
1211
import { generateUrl } from '@nextcloud/router'
1312
import { isPublicShare } from '@nextcloud/sharing/public'
13+
import { showError } from '@nextcloud/dialogs'
14+
import { t } from '@nextcloud/l10n'
1415
import { vOnClickOutside } from '@vueuse/components'
15-
import { extname } from 'path'
1616
import Vue, { computed, defineComponent } from 'vue'
1717

1818
import { action as sidebarAction } from '../actions/sidebarAction.ts'
19+
import { dataTransferToFileTree, onDropExternalFiles, onDropInternalFiles } from '../services/DropService.ts'
1920
import { getDragAndDropPreview } from '../utils/dragUtils.ts'
2021
import { hashCode } from '../utils/hashUtils.ts'
21-
import { dataTransferToFileTree, onDropExternalFiles, onDropInternalFiles } from '../services/DropService.ts'
22-
import logger from '../logger.ts'
2322
import { isDownloadable } from '../utils/permissions.ts'
23+
import logger from '../logger.ts'
2424

2525
Vue.directive('onClickOutside', vOnClickOutside)
2626

@@ -200,7 +200,20 @@ export default defineComponent({
200200
}
201201

202202
return actions
203-
.filter(action => !action.enabled || action.enabled([this.source], this.currentView))
203+
.filter(action => {
204+
if (!action.enabled) {
205+
return true
206+
}
207+
208+
// In case something goes wrong, since we don't want to break
209+
// the entire list, we filter out actions that throw an error.
210+
try {
211+
return action.enabled([this.source], this.currentView)
212+
} catch (error) {
213+
logger.error('Error while checking action', { action, error })
214+
return false
215+
}
216+
})
204217
.sort((a, b) => (a.order || 0) - (b.order || 0))
205218
},
206219

0 commit comments

Comments
 (0)