Skip to content

Standardize pipeline error shape across stages and web workflow#24

Open
Boykosoft wants to merge 1 commit intoOpen-scribe:mainfrom
Boykosoft:feat/shared-pipeline-errors
Open

Standardize pipeline error shape across stages and web workflow#24
Boykosoft wants to merge 1 commit intoOpen-scribe:mainfrom
Boykosoft:feat/shared-pipeline-errors

Conversation

@Boykosoft
Copy link

Summary

Introduce a shared PipelineError shape and apply it consistently across all four pipeline stages and the web workflow UI.

Problem

Each pipeline stage (audio-ingest, transcribe, assemble, note-core) handled errors differently — some threw plain Error, others returned ad-hoc objects, and the web app had no unified way to display failures or offer retry actions.

Solution

Shared error contract

  • New packages/pipeline/shared/src/error.ts with:
    • PipelineError interface (code, message, recoverable, details?)
    • PipelineStageError class extending Error
    • Helpers: createPipelineError, isPipelineError, toPipelineError, toPipelineStageError

Updated stages

  • audio-ingest — recorder failures normalized via toAudioIngestError
  • transcribe — WAV parsing, segment upload, and all 3 providers (Whisper, Whisper-local, MedASR) now throw PipelineStageError
  • assemblesession-store.emitError emits standardized error events
  • note-corecreateClinicalNoteText throws PipelineStageError on API failures

Web workflow

  • New WorkflowErrorDisplay component renders error message + conditional Retry button when recoverable: true
  • Integrated into apps/web/src/app/page.tsx

Tests

One test per stage confirming the standardized error shape:

  • audio-processing.test.ts — capture error normalization
  • transcribe.test.ts — WAV validation error shape
  • session-store.test.ts — assembly error emission
  • note-generator.test.ts — note generation failure shape

Closes #12

@@ -0,0 +1,22 @@
import assert from "node:assert/strict"
import test from "node:test"
import { transcriptionSessionStore } from "../session-store.js"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right now this import instantiates the global TranscriptionSessionStore singleton, which starts a perpetual setInterval in its constructor. With this new test now included in the test suite, the pnpm test:run hangs after tests pass due to open handles. Could you please add interval lifecycle safety (e.g., unref(), explicit dispose/teardown, or a non-singleton test instance) so the test runner can exit cleanly.

let message = `Final upload failed (${response.status})`
try {
const body = (await response.json()) as { error?: { message?: string } }
const body = (await response.json()) as { error?: PipelineError }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we parse a structured PipelineError here, but later the flow throws a plain Error(message). In the outer catch, toPipelineError(..., { recoverable: true }) can reclassify unrecoverable failures as recoverable and drop server-provided code/details. Please preserve and rethrow the parsed PipelineError (or PipelineStageError) rather than converting it to error.

if (body?.error?.message) {
message = body.error.message
}
if (body?.error) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add a test for final-upload failure propagation that verifies server-provided { code, message, recoverable, details } reaches workflow error state unchanged (no re-normalization to generic api_error/recoverable=true).

)
}

export function toPipelineError(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a great extraction. This honestly makes downstream stages much cleaner and reduces ad-hoc error mapping drift.

onRetry?: () => void
}

export function WorkflowErrorDisplay({ error, onRetry }: WorkflowErrorDisplayProps) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This helps pulling this into a dedicated component keeps page.tsx from growing

Copy link
Collaborator

@sammargolis sammargolis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a really great direction on standardizing pipeline errors and surfacing recoverability in the UI/API. I found two issues that should be addressed before merge. Right now (1) the test runner hang from session-store interval lifecycle, and (2) the final upload error rethrow dropping structured metadata/recoverability.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Improve error handling across pipeline stages

2 participants