fix(ai-fal): handle errors from fal result fetch on completed jobs#396
Conversation
Map fal.ai's FAILED queue status to 'failed' instead of falling through to the default case which incorrectly returned 'processing'. Unknown statuses now also map to 'failed' as a safety net. Error details from fal responses are surfaced in VideoStatusResult.error. Closes TanStack#394 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughUpdates fal.ai video adapter error handling and status mapping: bumps Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant Adapter
participant FalClient
participant Activity as VideoActivity
Client->>Adapter: createVideoJob / poll getVideoStatus(jobId)
Adapter->>FalClient: queue.status(jobId)
FalClient-->>Adapter: { status: "COMPLETED" | "FAILED" | ... , error? }
alt status == COMPLETED
Adapter->>FalClient: queue.result(jobId)
FalClient--xAdapter: throws validation/error (body.detail)
Adapter->>Activity: emit video:request:completed (status: 'failed', error)
Adapter-->>Client: return { status: 'failed', error, progress }
else status == FAILED
Adapter->>Activity: emit video:request:completed (status: 'failed', error)
Adapter-->>Client: return { status: 'failed', error }
else other/unknown
Adapter-->>Client: return { status: 'failed' }
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
View your CI Pipeline Execution ↗ for commit 20ff087
☁️ Nx Cloud last updated this comment at |
@tanstack/ai
@tanstack/ai-anthropic
@tanstack/ai-client
@tanstack/ai-devtools-core
@tanstack/ai-elevenlabs
@tanstack/ai-event-client
@tanstack/ai-fal
@tanstack/ai-gemini
@tanstack/ai-grok
@tanstack/ai-groq
@tanstack/ai-ollama
@tanstack/ai-openai
@tanstack/ai-openrouter
@tanstack/ai-preact
@tanstack/ai-react
@tanstack/ai-react-ui
@tanstack/ai-solid
@tanstack/ai-solid-ui
@tanstack/ai-svelte
@tanstack/ai-vue
@tanstack/ai-vue-ui
@tanstack/preact-ai-devtools
@tanstack/react-ai-devtools
@tanstack/solid-ai-devtools
commit: |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
packages/typescript/ai-fal/tests/video-adapter.test.ts (1)
217-227: Good safety net test for unknown statuses.This test ensures that any unrecognized status from fal.ai will result in
'failed'rather than continuing to poll indefinitely.Consider adding an edge case test for
FAILEDwithout an error message to ensure graceful handling:📝 Optional additional test case
it('returns failed status without error when error field is absent', async () => { mockQueueStatus.mockResolvedValueOnce({ status: 'FAILED', }) const adapter = createAdapter() const result = await adapter.getVideoStatus('job-failed-no-error') expect(result.status).toBe('failed') expect(result.error).toBeUndefined() })🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/typescript/ai-fal/tests/video-adapter.test.ts` around lines 217 - 227, Add a test that ensures the adapter maps a fal.ai response with status 'FAILED' but no error field to { status: 'failed' } and does not set an error message: create a new it block similar to the existing unknown status test, use mockQueueStatus.mockResolvedValueOnce({ status: 'FAILED' }), call createAdapter() and await adapter.getVideoStatus('job-failed-no-error'), then assert result.status === 'failed' and that result.error is undefined; reference mockQueueStatus, createAdapter, and getVideoStatus to locate where to add the test.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/typescript/ai-fal/src/adapters/video.ts`:
- Around line 19-26: Update the FalQueueStatus type to only include 'IN_QUEUE' |
'IN_PROGRESS' | 'COMPLETED' (remove 'FAILED') and ensure any failure detection
logic uses FalStatusResponse.error (i.e., check for status === 'COMPLETED' &&
error) rather than comparing to a non-existent 'FAILED' status; update the
FalStatusResponse type usage sites accordingly so callers handle
completed-with-error cases.
---
Nitpick comments:
In `@packages/typescript/ai-fal/tests/video-adapter.test.ts`:
- Around line 217-227: Add a test that ensures the adapter maps a fal.ai
response with status 'FAILED' but no error field to { status: 'failed' } and
does not set an error message: create a new it block similar to the existing
unknown status test, use mockQueueStatus.mockResolvedValueOnce({ status:
'FAILED' }), call createAdapter() and await
adapter.getVideoStatus('job-failed-no-error'), then assert result.status ===
'failed' and that result.error is undefined; reference mockQueueStatus,
createAdapter, and getVideoStatus to locate where to add the test.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 61ab5164-14e9-44be-8b98-008f8aa8a168
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (4)
.changeset/fix-fal-failed-status.mdpackages/typescript/ai-fal/package.jsonpackages/typescript/ai-fal/src/adapters/video.tspackages/typescript/ai-fal/tests/video-adapter.test.ts
fal.ai never returns a FAILED queue status — invalid jobs go through IN_PROGRESS → COMPLETED, and the real error (e.g. 422 validation) only surfaces when calling fal.queue.result(). This extracts detailed error info from the result fetch, removes the fictional FAILED status handling, and returns failed status from getVideoJobStatus when the result fetch throws. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Summary
FAILEDqueue status — invalid jobs goIN_PROGRESS→COMPLETED, and the real error (e.g. 422 validation) only surfaces when callingfal.queue.result()getVideoUrl()now catches result fetch errors and extracts detailed validation messages fromerror.body.detailFAILEDqueue status handling (fal doesn't use it)getVideoJobStatus()now returnsstatus: 'failed'when the result fetch throws on a "completed" job'processing'(safe for polling) instead of'failed'Closes #394
Test plan
getVideoUrl()'processing'🤖 Generated with Claude Code
Summary by CodeRabbit