refactor(server): rename Agent exception to Ai; add THREAD_NOT_FOUND / MESSAGE_NOT_FOUND codes (fixes 500s) (#19831)
## Summary - The exception class under `ai-agent/` was serving every AI surface (agent, chat, role, models, generate-text), so `Agent` was a misnomer. Promoted to the `ai/` namespace; renamed `AgentException` → `AiException`, `AgentExceptionCode` → `AiExceptionCode`, and related interceptor / filter / handler / file names accordingly. - Split the single `AGENT_NOT_FOUND` code into entity-specific codes. Chat-thread lookups no longer reuse the agent identifier. - **Fixes Sentry 500s on `GetChatMessages` / `chatThread`.** Every "Thread not found" and "Queued message not found" throw site in ai-chat was previously wired to `AGENT_EXECUTION_FAILED`, which maps to `InternalServerError` (HTTP 500). They now use `THREAD_NOT_FOUND` / `MESSAGE_NOT_FOUND`, both of which map to `NotFoundError` (HTTP 404) in the GraphQL and REST handlers. The underlying cause of *why* clients are asking for threads that no longer resolve for them — per-user chat-thread create events being broadcast workspace-wide — is addressed separately in a follow-up PR. ### Code map - Added: `ai/ai.exception.ts`, `ai/utils/ai-graphql-api-exception-handler.util.ts` (+ spec with new THREAD/MESSAGE cases), `ai/interceptors/ai-graphql-api-exception.interceptor.ts`, `ai/filters/ai-api-exception.filter.ts` - Deleted: `ai/ai-agent/agent.exception.ts`, `ai/ai-agent/utils/agent-graphql-api-exception-handler.util.ts` (+ spec), `ai/ai-agent/interceptors/agent-graphql-api-exception.interceptor.ts`, `ai/ai-agent/filters/agent-api-exception.filter.ts` - Updated: 21 call sites across ai-agent, ai-agent-execution, ai-agent-role, ai-chat, ai-generate-text, ai-models, role, and workspace-migration validators. ## Test plan - [x] `npx nx typecheck twenty-server` - [x] `npx jest ai-graphql-api-exception-handler` (3/3 including new THREAD_NOT_FOUND and MESSAGE_NOT_FOUND cases) - [x] `npx jest agent-role.service` (9/9) - [x] `npx oxlint --type-aware` on all changed files (0 warnings/errors) - [x] `npx prettier --check` on all changed files - [ ] CI
This commit is contained in:
+9
-9
@@ -5,9 +5,9 @@ import { type ActorMetadata } from 'twenty-shared/types';
|
||||
import { buildCreatedByFromFullNameMetadata } from 'src/engine/core-modules/actor/utils/build-created-by-from-full-name-metadata.util';
|
||||
import { UserWorkspaceService } from 'src/engine/core-modules/user-workspace/user-workspace.service';
|
||||
import {
|
||||
AgentException,
|
||||
AgentExceptionCode,
|
||||
} from 'src/engine/metadata-modules/ai/ai-agent/agent.exception';
|
||||
AiException,
|
||||
AiExceptionCode,
|
||||
} from 'src/engine/metadata-modules/ai/ai.exception';
|
||||
import { UserRoleService } from 'src/engine/metadata-modules/user-role/user-role.service';
|
||||
import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager';
|
||||
import { buildSystemAuthContext } from 'src/engine/twenty-orm/utils/build-system-auth-context.util';
|
||||
@@ -46,9 +46,9 @@ export class AgentActorContextService {
|
||||
await this.userWorkspaceService.findById(userWorkspaceId);
|
||||
|
||||
if (!userWorkspace) {
|
||||
throw new AgentException(
|
||||
throw new AiException(
|
||||
'User workspace not found',
|
||||
AgentExceptionCode.AGENT_EXECUTION_FAILED,
|
||||
AiExceptionCode.AGENT_EXECUTION_FAILED,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -72,9 +72,9 @@ export class AgentActorContextService {
|
||||
);
|
||||
|
||||
if (!workspaceMember) {
|
||||
throw new AgentException(
|
||||
throw new AiException(
|
||||
'Workspace member not found for user',
|
||||
AgentExceptionCode.AGENT_EXECUTION_FAILED,
|
||||
AiExceptionCode.AGENT_EXECUTION_FAILED,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -84,9 +84,9 @@ export class AgentActorContextService {
|
||||
});
|
||||
|
||||
if (!roleId) {
|
||||
throw new AgentException(
|
||||
throw new AiException(
|
||||
'User role not found',
|
||||
AgentExceptionCode.AGENT_EXECUTION_FAILED,
|
||||
AiExceptionCode.AGENT_EXECUTION_FAILED,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
+8
-8
@@ -23,9 +23,9 @@ import { countNativeWebSearchCallsFromSteps } from 'src/engine/metadata-modules/
|
||||
import { extractCacheCreationTokensFromSteps } from 'src/engine/metadata-modules/ai/ai-billing/utils/extract-cache-creation-tokens.util';
|
||||
import { mergeLanguageModelUsage } from 'src/engine/metadata-modules/ai/ai-billing/utils/merge-language-model-usage.util';
|
||||
import {
|
||||
AgentException,
|
||||
AgentExceptionCode,
|
||||
} from 'src/engine/metadata-modules/ai/ai-agent/agent.exception';
|
||||
AiException,
|
||||
AiExceptionCode,
|
||||
} from 'src/engine/metadata-modules/ai/ai.exception';
|
||||
import { AGENT_CONFIG } from 'src/engine/metadata-modules/ai/ai-agent/constants/agent-config.const';
|
||||
import { WORKFLOW_SYSTEM_PROMPTS } from 'src/engine/metadata-modules/ai/ai-agent/constants/agent-system-prompts.const';
|
||||
import { type AgentEntity } from 'src/engine/metadata-modules/ai/ai-agent/entities/agent.entity';
|
||||
@@ -239,9 +239,9 @@ export class AgentAsyncExecutorService {
|
||||
});
|
||||
|
||||
if (structuredResult.output == null) {
|
||||
throw new AgentException(
|
||||
throw new AiException(
|
||||
'Failed to generate structured output from execution results',
|
||||
AgentExceptionCode.AGENT_EXECUTION_FAILED,
|
||||
AiExceptionCode.AGENT_EXECUTION_FAILED,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -255,12 +255,12 @@ export class AgentAsyncExecutorService {
|
||||
nativeWebSearchCallCount,
|
||||
};
|
||||
} catch (error) {
|
||||
if (error instanceof AgentException) {
|
||||
if (error instanceof AiException) {
|
||||
throw error;
|
||||
}
|
||||
throw new AgentException(
|
||||
throw new AiException(
|
||||
error instanceof Error ? error.message : 'Agent execution failed',
|
||||
AgentExceptionCode.AGENT_EXECUTION_FAILED,
|
||||
AiExceptionCode.AGENT_EXECUTION_FAILED,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user