refactor: encapsulate error extraction in TaskItemImpl getters (#7650)

## Summary
- Add `errorMessage` and `executionError` getters to `TaskItemImpl` that
extract error info from status messages
- Update `useJobErrorReporting` composable to use these getters instead
of standalone function
- Remove the standalone `extractExecutionError` function

This encapsulates error extraction within `TaskItemImpl`, preparing for
the Jobs API migration where the underlying data format will change but
the getter interface will remain stable.

## Test plan
- [x] All existing tests pass
- [x] New tests added for `TaskItemImpl.errorMessage` and
`TaskItemImpl.executionError` getters
- [x] TypeScript, lint, and knip checks pass

🤖 Generated with [Claude Code](https://claude.com/claude-code)

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7650-refactor-encapsulate-error-extraction-in-TaskItemImpl-getters-2ce6d73d365081caae33dcc7e1e07720)
by [Unito](https://www.unito.io)

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Christian Byrne <cbyrne@comfy.org>
This commit is contained in:
ric-yu
2026-01-15 20:11:22 -08:00
committed by GitHub
parent 089295606a
commit c0a649ef43
46 changed files with 1650 additions and 3067 deletions

View File

@@ -1,39 +1,42 @@
import { ref, shallowRef } from 'vue'
import type { JobListItem } from '@/composables/queue/useJobList'
/** Minimal preview item interface for gallery filtering. */
interface PreviewItem {
url: string
supportsPreview: boolean
}
/** Minimal task interface for gallery preview. */
interface TaskWithPreview<T extends PreviewItem = PreviewItem> {
previewOutput?: T
}
import { findActiveIndex, getOutputsForTask } from '@/services/jobOutputCache'
import type { ResultItemImpl, TaskItemImpl } from '@/stores/queueStore'
/**
* Manages result gallery state and activation for queue items.
*/
export function useResultGallery<T extends PreviewItem>(
getFilteredTasks: () => TaskWithPreview<T>[]
) {
export function useResultGallery(getFilteredTasks: () => TaskItemImpl[]) {
const galleryActiveIndex = ref(-1)
const galleryItems = shallowRef<T[]>([])
const galleryItems = shallowRef<ResultItemImpl[]>([])
const onViewItem = (item: JobListItem) => {
const items: T[] = getFilteredTasks().flatMap((t) => {
const preview = t.previewOutput
return preview && preview.supportsPreview ? [preview] : []
})
async function onViewItem(item: JobListItem) {
const tasks = getFilteredTasks()
if (!tasks.length) return
const targetTask = item.taskRef
const targetOutputs = targetTask
? await getOutputsForTask(targetTask)
: null
// Request was superseded by a newer one
if (targetOutputs === null && targetTask) return
// Use target's outputs if available, otherwise fall back to all previews
const items = targetOutputs?.length
? targetOutputs
: tasks
.map((t) => t.previewOutput)
.filter((o): o is ResultItemImpl => !!o)
if (!items.length) return
galleryItems.value = items
const activeUrl: string | undefined = item.taskRef?.previewOutput?.url
const idx = activeUrl ? items.findIndex((o) => o.url === activeUrl) : 0
galleryActiveIndex.value = idx >= 0 ? idx : 0
galleryActiveIndex.value = findActiveIndex(
items,
item.taskRef?.previewOutput?.url
)
}
return {