fix(files): failsafe when executing actions methods

Signed-off-by: skjnldsv <skjnldsv@protonmail.com>
pull/49685/head
skjnldsv 2024-12-06 09:59:40 +07:00
parent 3baa91d842
commit 4470dd623c
2 changed files with 48 additions and 16 deletions

@ -163,7 +163,14 @@ export default defineComponent({
if (this.filesListWidth < 768 || this.gridMode) {
return []
}
return this.enabledFileActions.filter(action => action?.inline?.(this.source, this.currentView))
return this.enabledFileActions.filter(action => {
try {
return action?.inline?.(this.source, this.currentView)
} catch (error) {
logger.error('Error while checking if action is inline', { action, error })
return false
}
})
},
// Enabled action that are displayed inline with a custom render function
@ -236,13 +243,19 @@ export default defineComponent({
methods: {
actionDisplayName(action: FileAction) {
if ((this.gridMode || (this.filesListWidth < 768 && action.inline)) && typeof action.title === 'function') {
// if an inline action is rendered in the menu for
// lack of space we use the title first if defined
const title = action.title([this.source], this.currentView)
if (title) return title
try {
if ((this.gridMode || (this.filesListWidth < 768 && action.inline)) && typeof action.title === 'function') {
// if an inline action is rendered in the menu for
// lack of space we use the title first if defined
const title = action.title([this.source], this.currentView)
if (title) return title
}
return action.displayName([this.source], this.currentView)
} catch (error) {
logger.error('Error while getting action display name', { action, error })
// Not ideal, but better than nothing
return action.id
}
return action.displayName([this.source], this.currentView)
},
async onActionClick(action, isSubmenu = false) {
@ -257,7 +270,13 @@ export default defineComponent({
return
}
const displayName = action.displayName([this.source], this.currentView)
let displayName = action.id
try {
displayName = action.displayName([this.source], this.currentView)
} catch (error) {
logger.error('Error while getting action display name', { action, error })
}
try {
// Set the loading marker
this.$emit('update:loading', action.id)
@ -275,8 +294,8 @@ export default defineComponent({
return
}
showError(t('files', '"{displayName}" action failed', { displayName }))
} catch (e) {
logger.error('Error while executing action', { action, e })
} catch (error) {
logger.error('Error while executing action', { action, error })
showError(t('files', '"{displayName}" action failed', { displayName }))
} finally {
// Reset the loading marker

@ -6,21 +6,21 @@
import type { PropType } from 'vue'
import type { FileSource } from '../types.ts'
import { showError } from '@nextcloud/dialogs'
import { extname } from 'path'
import { FileType, Permission, Folder, File as NcFile, NodeStatus, Node, getFileActions } from '@nextcloud/files'
import { translate as t } from '@nextcloud/l10n'
import { generateUrl } from '@nextcloud/router'
import { isPublicShare } from '@nextcloud/sharing/public'
import { showError } from '@nextcloud/dialogs'
import { t } from '@nextcloud/l10n'
import { vOnClickOutside } from '@vueuse/components'
import { extname } from 'path'
import Vue, { computed, defineComponent } from 'vue'
import { action as sidebarAction } from '../actions/sidebarAction.ts'
import { dataTransferToFileTree, onDropExternalFiles, onDropInternalFiles } from '../services/DropService.ts'
import { getDragAndDropPreview } from '../utils/dragUtils.ts'
import { hashCode } from '../utils/hashUtils.ts'
import { dataTransferToFileTree, onDropExternalFiles, onDropInternalFiles } from '../services/DropService.ts'
import logger from '../logger.ts'
import { isDownloadable } from '../utils/permissions.ts'
import logger from '../logger.ts'
Vue.directive('onClickOutside', vOnClickOutside)
@ -200,7 +200,20 @@ export default defineComponent({
}
return actions
.filter(action => !action.enabled || action.enabled([this.source], this.currentView))
.filter(action => {
if (!action.enabled) {
return true
}
// In case something goes wrong, since we don't want to break
// the entire list, we filter out actions that throw an error.
try {
return action.enabled([this.source], this.currentView)
} catch (error) {
logger.error('Error while checking action', { action, error })
return false
}
})
.sort((a, b) => (a.order || 0) - (b.order || 0))
},