Add controller error-path tests, channel error reporting, and document OpenAI resilience config#262
Add controller error-path tests, channel error reporting, and document OpenAI resilience config#262Copilot wants to merge 4 commits into
Conversation
|
@copilot i am only concerned with two things: not crashing the app and reporting openAI errors to <#CKCL8UMJA> channel |
|
@copilot this does not achieve the goal - ensure that errors from openai result in a slack post to <#CKCL8UMJA>, and that errors are not thrown/uncaught in such a way that the service crashes |
There was a problem hiding this comment.
Pull request overview
Adds missing error-path coverage for AI controller endpoints to ensure OpenAI/service failures don’t crash Slack slash-command handlers, and documents the resilience-related environment variables/behavior for the OpenAI wrapper.
Changes:
- Added controller tests verifying
/imageand/prompt-with-historystill return 200 and send an ephemeral message when the underlying service rejects. - Tightened the existing
/texterror-path test to assertsendEphemeralarguments. - Expanded README with the OpenAI resilience env vars and an “OpenAI Error Handling” subsection describing retry/circuit-breaker/timeout/bulkhead behavior.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| README.md | Documents OpenAI resilience env vars and explains error-handling behavior. |
| packages/backend/src/ai/ai.controller.spec.ts | Adds/strengthens controller-level tests for error paths across AI endpoints. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Done. The |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
| void webService.sendMessage( | ||
| '#muzzlefeedback', | ||
| `AI /image error for <@${user_id}>: ${e instanceof Error ? e.message : String(e)}`, | ||
| ); |
| void webService.sendMessage( | ||
| '#muzzlefeedback', | ||
| `AI /prompt-with-history error for <@${request.user_id}>: ${e instanceof Error ? e.message : String(e)}`, | ||
| ); |
| | **Timeout** | Each individual request is aborted after `OPENAI_TIMEOUT_MS` milliseconds. | | ||
| | **Concurrency limiter** | At most `OPENAI_CONCURRENCY` calls are in-flight at once; excess requests are rejected immediately. | | ||
| | **Prometheus metrics** | Counters and histograms for requests, retries, failures, circuit opens, and latency are registered via `prom-client` (expose the registry on a `/metrics` endpoint if desired). | | ||
| | **Slack alert on 429** | When the rate-limit error reaches the application layer, an alert is posted to `#muzzlefeedback`. | |
| await Promise.resolve(); | ||
| expect(sendEphemeral).toHaveBeenCalled(); | ||
| expect(sendEphemeral).toHaveBeenCalledWith('C1', expect.stringContaining('hello'), 'U1'); | ||
| expect(sendMessage).toHaveBeenCalledWith('#muzzlefeedback', expect.stringContaining('boom')); |
|
|
||
| await Promise.resolve(); | ||
| expect(sendEphemeral).toHaveBeenCalledWith('C1', expect.stringContaining('draw a cat'), 'U1'); | ||
| expect(sendMessage).toHaveBeenCalledWith('#muzzlefeedback', expect.stringContaining('image boom')); |
|
|
||
| await Promise.resolve(); | ||
| expect(sendEphemeral).toHaveBeenCalledWith('C1', expect.stringContaining('summarize'), 'U1'); | ||
| expect(sendMessage).toHaveBeenCalledWith('#muzzlefeedback', expect.stringContaining('history boom')); |
| void webService.sendMessage( | ||
| '#muzzlefeedback', | ||
| `AI /text error for <@${user_id}>: ${e instanceof Error ? e.message : String(e)}`, | ||
| ); |
The app lacked test coverage proving OpenAI failures don't crash the
/imageand/prompt-with-historyendpoints, AI errors were not being reported to the#muzzlefeedbackchannel for non-429 failures, and the resilience configuration env vars were undocumented.Changes
Error Reporting (
ai.controller.ts)/text,/image,/prompt-with-history) now post to#muzzlefeedbackwhenever the underlying service rejects, ensuring every AI failure is visible in the error channel — not just 429 rate-limit errorsTests (
ai.controller.spec.ts)sendMessageto theWebServicemock#muzzlefeedbackchannel notification are sent on failure/imageand/prompt-with-history— each verifies the endpoint still returns 200 when the underlying service rejectsDocumentation (
README.md).envexample block with inline defaultsOPENAI_TIMEOUT_MS10000OPENAI_RETRIES3OPENAI_BACKOFF_BASE_MS500CIRCUIT_BREAKER_FAILURES5CIRCUIT_BREAKER_WINDOW_MS60000CIRCUIT_BREAKER_PROBE_MS30000OPENAI_CONCURRENCY10FEATURE_FLAG_RESILIENT_OPENAItruefalseOriginal prompt
This pull request was created from Copilot chat.