Skip to content

Commit 94e8838

Browse files
committed
fix: classify no-speech errors across workflow realms
1 parent 0b95eee commit 94e8838

2 files changed

Lines changed: 14 additions & 5 deletions

File tree

apps/web/__tests__/integration/transcribe-workflow.test.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,12 @@ vi.mock("drizzle-orm", () => ({
9898

9999
vi.mock("server-only", () => ({}));
100100

101-
vi.mock("workflow", () => ({
102-
FatalError: class FatalError extends Error {},
103-
}));
101+
vi.mock("workflow", async () => {
102+
const { runInNewContext } = await import("node:vm");
103+
return {
104+
FatalError: runInNewContext("(class FatalError extends Error {})"),
105+
};
106+
});
104107

105108
vi.mock("workflow/api", () => ({
106109
start: vi.fn(),
@@ -245,7 +248,9 @@ describe("transcribeVideoWorkflow", () => {
245248
expect(mocks.updates.at(-1)).toEqual({ transcriptionStatus: "COMPLETE" });
246249
});
247250

248-
it("marks audio without speech as skipped without retrying transcription", async () => {
251+
it("handles no-speech errors across workflow realms without retrying transcription", async () => {
252+
const { FatalError } = await import("workflow");
253+
expect(new FatalError("no spoken audio")).not.toBeInstanceOf(Error);
249254
mocks.transcribe.mockResolvedValueOnce({
250255
id: "silent-transcript",
251256
status: "error",
@@ -268,6 +273,7 @@ describe("transcribeVideoWorkflow", () => {
268273
expect(mocks.updates).toContainEqual({ transcriptionStatus: "NO_AUDIO" });
269274
expect(mocks.updates).not.toContainEqual({ transcriptionStatus: "ERROR" });
270275
expect(mocks.startAiGeneration).not.toHaveBeenCalled();
276+
expect(mocks.deleteObject).toHaveBeenCalledTimes(1);
271277
});
272278

273279
it("preserves transcription failures unrelated to missing speech", async () => {

apps/web/workflows/transcribe.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,10 @@ export async function transcribeVideoWorkflow(
162162
await saveTranscription(videoId, userId, videoData.video, transcription);
163163
} catch (error) {
164164
if (
165-
error instanceof Error &&
165+
typeof error === "object" &&
166+
error !== null &&
167+
"message" in error &&
168+
typeof error.message === "string" &&
166169
error.message.toLowerCase().includes("no spoken audio")
167170
) {
168171
await markNoAudio(videoId);

0 commit comments

Comments
 (0)