diff --git a/apps/trigger/src/tasks/message-post-processing/message-post-processing.int.test.ts b/apps/trigger/src/tasks/message-post-processing/message-post-processing.int.test.ts index 7e21e35cd..0754a9887 100644 --- a/apps/trigger/src/tasks/message-post-processing/message-post-processing.int.test.ts +++ b/apps/trigger/src/tasks/message-post-processing/message-post-processing.int.test.ts @@ -125,7 +125,7 @@ describe.skipIf(skipIntegrationTests)('messagePostProcessingTask integration', ( it('should handle message with no conversation history', async () => { // Use prepopulated message ID - const messageId = 'a3206f20-35d1-4a6c-84a7-48f8f222c39f'; + const messageId = '203744bd-439f-4b3c-9ea2-ddfe243c5afe'; // Execute task const result = await tasks.triggerAndPoll( diff --git a/apps/trigger/src/tasks/message-post-processing/message-post-processing.ts b/apps/trigger/src/tasks/message-post-processing/message-post-processing.ts index dd48279d8..fb4194c1d 100644 --- a/apps/trigger/src/tasks/message-post-processing/message-post-processing.ts +++ b/apps/trigger/src/tasks/message-post-processing/message-post-processing.ts @@ -180,7 +180,14 @@ export const messagePostProcessingTask: ReturnType< // Handle branch results - the result will have one of the branch step IDs as a key let validatedOutput: PostProcessingWorkflowOutput; - const branchResult = workflowResult.result as any; // Type assertion needed for branch results + + // Define the expected shape of branch results + type BranchResult = { + 'format-follow-up-message'?: PostProcessingWorkflowOutput; + 'format-initial-message'?: PostProcessingWorkflowOutput; + }; + + const branchResult = workflowResult.result as BranchResult; if ('format-follow-up-message' in branchResult && branchResult['format-follow-up-message']) { validatedOutput = branchResult['format-follow-up-message'] as PostProcessingWorkflowOutput; @@ -195,6 +202,11 @@ export const messagePostProcessingTask: ReturnType< resultKeys: Object.keys(branchResult), result: branchResult, }); + console.error('Unexpected workflow result structure:', { + messageId: payload.messageId, + resultKeys: Object.keys(branchResult), + result: branchResult, + }); throw new Error('Post-processing workflow returned unexpected result structure'); } @@ -214,53 +226,93 @@ export const messagePostProcessingTask: ReturnType< messageId: payload.messageId, }); - const db = getDb(); - const dbData = extractDbFields(validatedOutput, messageContext.userName); - await db - .update(messages) - .set({ - postProcessingMessage: dbData, - updatedAt: new Date().toISOString(), - }) - .where(eq(messages.id, payload.messageId)); + + try { + const db = getDb(); + await db + .update(messages) + .set({ + postProcessingMessage: dbData, + updatedAt: new Date().toISOString(), + }) + .where(eq(messages.id, payload.messageId)); + + logger.log('Database update successful', { + messageId: payload.messageId, + }); + } catch (dbError) { + const errorMessage = dbError instanceof Error ? dbError.message : 'Unknown database error'; + logger.error('Failed to update database with post-processing result', { + messageId: payload.messageId, + error: errorMessage, + }); + console.error('Failed to update database with post-processing result:', { + messageId: payload.messageId, + error: errorMessage, + stack: dbError instanceof Error ? dbError.stack : undefined, + }); + // Throw the error to ensure the task fails when database update fails + throw new Error(`Database update failed: ${errorMessage}`); + } // Step 6: Send Slack notification if conditions are met - logger.log('Checking Slack notification conditions', { - messageId: payload.messageId, - organizationId: messageContext.organizationId, - summaryTitle: dbData.summaryTitle, - summaryMessage: dbData.summaryMessage, - formattedMessage: dbData.formattedMessage, - toolCalled: dbData.toolCalled, - }); + let slackNotificationSent = false; - const slackResult = await sendSlackNotification({ - organizationId: messageContext.organizationId, - userName: messageContext.userName, - summaryTitle: dbData.summaryTitle, - summaryMessage: dbData.summaryMessage, - formattedMessage: dbData.formattedMessage, - toolCalled: dbData.toolCalled, - message: dbData.message, - }); - - if (slackResult.sent) { - logger.log('Slack notification sent successfully', { + try { + logger.log('Checking Slack notification conditions', { messageId: payload.messageId, organizationId: messageContext.organizationId, + summaryTitle: dbData.summaryTitle, + summaryMessage: dbData.summaryMessage, + formattedMessage: dbData.formattedMessage, + toolCalled: dbData.toolCalled, }); - } else { - logger.log('Slack notification not sent', { + + const slackResult = await sendSlackNotification({ + organizationId: messageContext.organizationId, + userName: messageContext.userName, + summaryTitle: dbData.summaryTitle, + summaryMessage: dbData.summaryMessage, + formattedMessage: dbData.formattedMessage, + toolCalled: dbData.toolCalled, + message: dbData.message, + }); + + if (slackResult.sent) { + slackNotificationSent = true; + logger.log('Slack notification sent successfully', { + messageId: payload.messageId, + organizationId: messageContext.organizationId, + }); + } else { + logger.log('Slack notification not sent', { + messageId: payload.messageId, + organizationId: messageContext.organizationId, + reason: slackResult.error, + }); + } + } catch (slackError) { + const errorMessage = + slackError instanceof Error ? slackError.message : 'Unknown Slack error'; + logger.error('Failed to send Slack notification', { messageId: payload.messageId, organizationId: messageContext.organizationId, - reason: slackResult.error, + error: errorMessage, }); + console.error('Failed to send Slack notification:', { + messageId: payload.messageId, + organizationId: messageContext.organizationId, + error: errorMessage, + stack: slackError instanceof Error ? slackError.stack : undefined, + }); + // Don't throw - this is a non-critical error } logger.log('Message post-processing completed successfully', { messageId: payload.messageId, executionTimeMs: Date.now() - startTime, + slackNotificationSent, }); // Wait 500ms to allow Braintrust to clean up its trace before completing @@ -285,6 +337,13 @@ export const messagePostProcessingTask: ReturnType< executionTimeMs: Date.now() - startTime, }); + console.error('Post-processing task execution failed:', { + messageId: payload.messageId, + error: errorMessage, + stack: error instanceof Error ? error.stack : undefined, + executionTimeMs: Date.now() - startTime, + }); + return { success: false, messageId: payload.messageId,