chore(utils): migrate to shared random/ID utilities and add enforcement linting (#4623)

* chore(utils): migrate to shared random/ID utilities and add enforcement linting

- Replace all Math.random(), crypto.randomUUID(), crypto.randomBytes(), nanoid, and uuid usages with shared @sim/utils/random and @sim/utils/id helpers across 72 files
- Add new @sim/utils exports: deepClone, omit, filterUndefined (object), truncate (string), backoffWithJitter, parseRetryAfter (retry), getErrorMessage (errors)
- Sweep all getErrorMessage, sleep, deepClone callsites across 500+ files to use shared utilities
- Add Biome noRestrictedImports rule to catch nanoid, uuid, and crypto named imports at lint time
- Add scripts/check-utils-enforcement.ts to catch Math.random and crypto.* global property access
- Add check:utils script to package.json

* chore(utils): replace deepClone wrapper with structuredClone built-in

deepClone() was a one-line wrapper around structuredClone(), which is
universally available in Node 17+ and all modern browsers. Removing the
abstraction reduces indirection and means contributors don't need to
learn a project-specific name for a well-known built-in.

- Remove deepClone from packages/utils/src/object.ts and index.ts
- Replace all 17 call sites with structuredClone() directly
- Update check:utils script suggestion text
- Update CLAUDE.md and global.md docs

* fix(utils): add missing biome noRestrictedImports rule and correct truncate docs

- Add noRestrictedImports to biome.json under style — bans nanoid and uuid
  package imports at lint time (crypto.randomUUID/randomBytes are caught by
  the check:utils grep script which handles global property access)
- Correct truncate() TSDoc and parameter name: sliceLength makes it clear
  that total output length is sliceLength + suffix.length, matching the
  behavior all callers were already written to expect

* fix(utils): add missing getErrorMessage imports at 4 call sites

The sweep agents added getErrorMessage calls without the corresponding
import in 4 files, causing test failures. Added the missing imports.

* fix(utils): fix build errors from getErrorMessage sweep and retry.ts Turbopack issue

- Fix retry.ts cross-file import: Turbopack cannot resolve './random.js' for
  internal package imports; inline the jitter crypto call directly
- Add missing getErrorMessage imports to 32 files where the sweep added calls
  without the corresponding import (caught by type-check and test runs)
- Remove accidental getErrorMessage import from crowdstrike/query/route.ts
  which has its own domain-specific getErrorMessage for parsing CrowdStrike's
  JSON error format
- Fix use-sub-block-value.ts type error from structuredClone narrowing:
  add 'as T' cast at emitValue callsite (safe — valueCopy is always a
  structural copy of newValue)

* fix(tools): use toError in crowdstrike catch block instead of local getErrorMessage

The catch block was calling the local getErrorMessage function which
parses CrowdStrike API JSON responses, not JavaScript Error objects.
Use toError(error).message to correctly extract the message from a
caught value in this context.
This commit is contained in:
Waleed
2026-05-15 17:31:27 -07:00
committed by GitHub
parent c403fafd11
commit 8d7bbbc670
534 changed files with 1679 additions and 1050 deletions
+17 -8
View File
@@ -36,22 +36,31 @@ const tiny = generateShortId(8)
## Common Utilities
Use shared helpers from `@sim/utils` instead of writing inline implementations:
- `sleep(ms)` — async delay. Never write `new Promise(resolve => setTimeout(resolve, ms))`
- `toError(value)` — normalize unknown caught values to `Error`. Never write `e instanceof Error ? e : new Error(String(e))`
- `toError(value).message` — get error message safely. Never write `e instanceof Error ? e.message : String(e)`
- `sleep(ms)` from `@sim/utils/helpers` — async delay. Never write `new Promise(resolve => setTimeout(resolve, ms))`
- `toError(value)` from `@sim/utils/errors` — normalize unknown caught values to `Error`. Never write `e instanceof Error ? e : new Error(String(e))`
- `getErrorMessage(value, fallback?)` from `@sim/utils/errors` — extract error message string. Never write `e instanceof Error ? e.message : 'fallback'`
- `structuredClone(value)` — built-in deep clone, no import needed. Never write `JSON.parse(JSON.stringify(obj))`
- `omit(obj, keys)` from `@sim/utils/object` — remove keys from object
- `filterUndefined(obj)` from `@sim/utils/object` — strip undefined-valued keys. Never write `Object.fromEntries(Object.entries(obj).filter(([, v]) => v !== undefined))`
- `truncate(str, maxLength, suffix?)` from `@sim/utils/string` — safe string truncation with ellipsis
- `backoffWithJitter(attempt, retryAfterMs, options?)` from `@sim/utils/retry` — exponential backoff with jitter
- `parseRetryAfter(header)` from `@sim/utils/retry` — parse HTTP `Retry-After` header to milliseconds
```typescript
// ✗ Bad
await new Promise(resolve => setTimeout(resolve, 1000))
const msg = error instanceof Error ? error.message : String(error)
const err = error instanceof Error ? error : new Error(String(error))
const msg = error instanceof Error ? error.message : 'Unknown error'
const clone = JSON.parse(JSON.stringify(obj))
const filtered = Object.fromEntries(Object.entries(obj).filter(([, v]) => v !== undefined))
// ✓ Good
import { sleep } from '@sim/utils/helpers'
import { toError } from '@sim/utils/errors'
import { getErrorMessage, toError } from '@sim/utils/errors'
import { filterUndefined } from '@sim/utils/object'
await sleep(1000)
const msg = toError(error).message
const err = toError(error)
const msg = getErrorMessage(error, 'Unknown error')
const clone = structuredClone(obj)
const filtered = filterUndefined(obj)
```
## Package Manager
+8 -1
View File
@@ -10,7 +10,14 @@ You are a professional software engineer. All code must follow best practices: a
- **Comments**: Use TSDoc for documentation. No `====` separators. No non-TSDoc comments
- **Styling**: Never update global styles. Keep all styling local to components
- **ID Generation**: Never use `crypto.randomUUID()`, `nanoid`, or `uuid` package. Use `generateId()` (UUID v4) or `generateShortId()` (compact) from `@sim/utils/id`
- **Common Utilities**: Use shared helpers from `@sim/utils` instead of inline implementations. `sleep(ms)` from `@sim/utils/helpers` for delays, `toError(e)` from `@sim/utils/errors` to normalize caught values.
- **Common Utilities**: Use shared helpers from `@sim/utils` instead of inline implementations:
- `sleep(ms)` from `@sim/utils/helpers` — never `new Promise(resolve => setTimeout(resolve, ms))`
- `toError(e)` from `@sim/utils/errors` — normalize caught values to `Error`
- `getErrorMessage(e, fallback?)` from `@sim/utils/errors` — extract message string from unknown caught value; never write `e instanceof Error ? e.message : 'fallback'`
- `structuredClone(value)` — built-in deep clone; never `JSON.parse(JSON.stringify(...))`
- `omit(obj, keys)` / `filterUndefined(obj)` from `@sim/utils/object` — object trimming; never `Object.fromEntries(Object.entries(...).filter(...))`
- `truncate(str, maxLength, suffix?)` from `@sim/utils/string` — never inline slice + ellipsis
- `backoffWithJitter(attempt, retryAfterMs, options?)` / `parseRetryAfter(header)` from `@sim/utils/retry` — shared retry pacing; never reimplement exponential backoff inline
- **Package Manager**: Use `bun` and `bunx`, not `npm` and `npx`
## Architecture
+2 -1
View File
@@ -13,6 +13,7 @@ import {
VARIABLE_OPERATIONS,
WORKFLOW_OPERATIONS,
} from '@sim/realtime-protocol/constants'
import { randomFloat } from '@sim/utils/random'
import { getActiveWorkflowContext } from '@sim/workflow-authz'
import { loadWorkflowFromNormalizedTablesRaw } from '@sim/workflow-persistence/load'
import { mergeSubBlockValues } from '@sim/workflow-persistence/subblocks'
@@ -204,7 +205,7 @@ export async function persistWorkflowOperation(workflowId: string, operation: an
throw new Error(`Workflow ${workflowId} is archived or unavailable`)
}
if (op === BLOCK_OPERATIONS.UPDATE_POSITION && Math.random() < 0.01) {
if (op === BLOCK_OPERATIONS.UPDATE_POSITION && randomFloat() < 0.01) {
logger.debug('Socket DB operation sample:', {
operation: op,
target,
+4 -3
View File
@@ -9,6 +9,7 @@ import {
WORKFLOW_OPERATIONS,
} from '@sim/realtime-protocol/constants'
import { WorkflowOperationSchema } from '@sim/realtime-protocol/schemas'
import { getErrorMessage } from '@sim/utils/errors'
import { generateId } from '@sim/utils/id'
import { assertWorkflowMutable, WorkflowLockedError } from '@sim/workflow-authz'
import { ZodError } from 'zod'
@@ -205,7 +206,7 @@ export function setupOperationsHandlers(socket: AuthenticatedSocket, roomManager
if (operationId) {
socket.emit('operation-failed', {
operationId,
error: error instanceof Error ? error.message : 'Database persistence failed',
error: getErrorMessage(error, 'Database persistence failed'),
retryable: true,
})
}
@@ -247,7 +248,7 @@ export function setupOperationsHandlers(socket: AuthenticatedSocket, roomManager
if (operationId) {
socket.emit('operation-failed', {
operationId,
error: error instanceof Error ? error.message : 'Database persistence failed',
error: getErrorMessage(error, 'Database persistence failed'),
retryable: true,
})
}
@@ -587,7 +588,7 @@ export function setupOperationsHandlers(socket: AuthenticatedSocket, roomManager
})
}
} catch (error) {
const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred'
const errorMessage = getErrorMessage(error, 'Unknown error occurred')
if (operationId) {
socket.emit('operation-failed', {
+3 -2
View File
@@ -2,6 +2,7 @@ import { db } from '@sim/db'
import { workflow, workflowBlocks } from '@sim/db/schema'
import { createLogger } from '@sim/logger'
import { SUBBLOCK_OPERATIONS } from '@sim/realtime-protocol/constants'
import { getErrorMessage } from '@sim/utils/errors'
import { assertWorkflowMutable, WorkflowLockedError } from '@sim/workflow-authz'
import { isWorkflowBlockProtected } from '@sim/workflow-types/workflow'
import { and, eq } from 'drizzle-orm'
@@ -208,7 +209,7 @@ export function setupSubblocksHandlers(socket: AuthenticatedSocket, roomManager:
} catch (error) {
logger.error('Error handling subblock update:', error)
const errorMessage = error instanceof Error ? error.message : 'Unknown error'
const errorMessage = getErrorMessage(error, 'Unknown error')
if (operationId) {
socket.emit('operation-failed', {
@@ -360,7 +361,7 @@ async function flushSubblockUpdate(
pending.opToSocket.forEach((socketId, opId) => {
io.to(socketId).emit('operation-failed', {
operationId: opId,
error: error instanceof Error ? error.message : 'Unknown error',
error: getErrorMessage(error, 'Unknown error'),
retryable: true,
})
})
+3 -2
View File
@@ -2,6 +2,7 @@ import { db } from '@sim/db'
import { workflow } from '@sim/db/schema'
import { createLogger } from '@sim/logger'
import { VARIABLE_OPERATIONS } from '@sim/realtime-protocol/constants'
import { getErrorMessage } from '@sim/utils/errors'
import { assertWorkflowMutable, WorkflowLockedError } from '@sim/workflow-authz'
import { eq } from 'drizzle-orm'
import type { AuthenticatedSocket } from '@/middleware/auth'
@@ -195,7 +196,7 @@ export function setupVariablesHandlers(socket: AuthenticatedSocket, roomManager:
} catch (error) {
logger.error('Error handling variable update:', error)
const errorMessage = error instanceof Error ? error.message : 'Unknown error'
const errorMessage = getErrorMessage(error, 'Unknown error')
if (operationId) {
socket.emit('operation-failed', {
@@ -326,7 +327,7 @@ async function flushVariableUpdate(
pending.opToSocket.forEach((socketId, opId) => {
io.to(socketId).emit('operation-failed', {
operationId: opId,
error: error instanceof Error ? error.message : 'Unknown error',
error: getErrorMessage(error, 'Unknown error'),
retryable: true,
})
})
+3 -2
View File
@@ -5,6 +5,7 @@
*/
import { createServer, request as httpRequest } from 'http'
import { createMockLogger } from '@sim/testing'
import { randomInt } from '@sim/utils/random'
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest'
import { createSocketIOServer } from '@/config/socket'
import { MemoryRoomManager } from '@/rooms'
@@ -95,7 +96,7 @@ describe('Socket Server Index Integration', () => {
})
beforeEach(async () => {
PORT = 3333 + Math.floor(Math.random() * 1000)
PORT = 3333 + randomInt(0, 1000)
httpServer = createServer()
@@ -120,7 +121,7 @@ describe('Socket Server Index Integration', () => {
httpServer.on('error', (err: any) => {
clearTimeout(timeout)
if (err.code === 'EADDRINUSE') {
PORT = 3333 + Math.floor(Math.random() * 1000)
PORT = 3333 + randomInt(0, 1000)
httpServer.close(() => {
httpServer.listen(PORT, '0.0.0.0', () => {
resolve()
+3 -3
View File
@@ -2,6 +2,7 @@
import { useEffect, useRef, useState } from 'react'
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { Eye, EyeOff } from 'lucide-react'
import Link from 'next/link'
import { useRouter, useSearchParams } from 'next/navigation'
@@ -292,8 +293,7 @@ export default function LoginPage({
},
})
} catch (requestError) {
let errorMessage =
requestError instanceof Error ? requestError.message : 'Failed to request password reset'
let errorMessage = getErrorMessage(requestError, 'Failed to request password reset')
if (
errorMessage.includes('Invalid body parameters') ||
@@ -325,7 +325,7 @@ export default function LoginPage({
logger.error('Error requesting password reset:', { error })
setResetStatus({
type: 'error',
message: error instanceof Error ? error.message : 'Failed to request password reset',
message: getErrorMessage(error, 'Failed to request password reset'),
})
} finally {
setIsSubmittingReset(false)
@@ -2,6 +2,7 @@
import { Suspense, useState } from 'react'
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import Link from 'next/link'
import { useRouter, useSearchParams } from 'next/navigation'
import { requestJson } from '@/lib/api/client/request'
@@ -53,7 +54,7 @@ function ResetPasswordContent() {
logger.error('Error resetting password:', { error })
setStatusMessage({
type: 'error',
text: error instanceof Error ? error.message : 'Failed to reset password',
text: getErrorMessage(error, 'Failed to reset password'),
})
} finally {
setIsSubmitting(false)
@@ -2,6 +2,7 @@ import type { Artifact, Message, PushNotificationConfig, TaskState } from '@a2a-
import { db } from '@sim/db'
import { a2aAgent, a2aPushNotificationConfig, a2aTask, workflow } from '@sim/db/schema'
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { generateId } from '@sim/utils/id'
import { and, eq, isNull } from 'drizzle-orm'
import { type NextRequest, NextResponse } from 'next/server'
@@ -1394,7 +1395,7 @@ async function handleTaskResubscribe(
logger.error('Error during SSE poll:', error)
sendEvent('error', {
code: A2A_ERROR_CODES.INTERNAL_ERROR,
message: error instanceof Error ? error.message : 'Polling failed',
message: getErrorMessage(error, 'Polling failed'),
})
cleanup()
try {
+3 -2
View File
@@ -1,5 +1,6 @@
import { db } from '@sim/db'
import { settings, user } from '@sim/db/schema'
import { getErrorMessage } from '@sim/utils/errors'
import { eq } from 'drizzle-orm'
import { type NextRequest, NextResponse } from 'next/server'
import { adminMothershipQuerySchema } from '@/lib/api/contracts/mothership-tasks'
@@ -109,7 +110,7 @@ export const POST = withRouteHandler(async (req: NextRequest) => {
} catch (error) {
return NextResponse.json(
{
error: `Failed to reach mothership (${environment}): ${error instanceof Error ? error.message : 'Unknown error'}`,
error: `Failed to reach mothership (${environment}): ${getErrorMessage(error, 'Unknown error')}`,
},
{ status: 502 }
)
@@ -165,7 +166,7 @@ export const GET = withRouteHandler(async (req: NextRequest) => {
} catch (error) {
return NextResponse.json(
{
error: `Failed to reach mothership (${environment}): ${error instanceof Error ? error.message : 'Unknown error'}`,
error: `Failed to reach mothership (${environment}): ${getErrorMessage(error, 'Unknown error')}`,
},
{ status: 502 }
)
+2 -1
View File
@@ -1,4 +1,5 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { listAuditLogsContract } from '@/lib/api/contracts/audit-logs'
import { getValidationErrorMessage, parseRequest } from '@/lib/api/server'
@@ -78,7 +79,7 @@ export const GET = withRouteHandler(async (request: NextRequest) => {
nextCursor,
})
} catch (error: unknown) {
const message = error instanceof Error ? error.message : 'Unknown error'
const message = getErrorMessage(error, 'Unknown error')
logger.error('Audit logs fetch error', { error: message })
return NextResponse.json({ error: 'Internal server error' }, { status: 500 })
}
+2 -1
View File
@@ -1,4 +1,5 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import {
oauthTokenGetContract,
@@ -97,7 +98,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
return NextResponse.json({ accessToken }, { status: 200 })
} catch (error) {
const message = error instanceof Error ? error.message : 'Failed to get OAuth token'
const message = getErrorMessage(error, 'Failed to get OAuth token')
logger.warn(`[${requestId}] OAuth token error: ${message}`)
return NextResponse.json({ error: message }, { status: 403 })
}
+4 -3
View File
@@ -1,5 +1,6 @@
import { db, member, ssoProvider } from '@sim/db'
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { and, eq } from 'drizzle-orm'
import { type NextRequest, NextResponse } from 'next/server'
import { ssoRegistrationContract } from '@/lib/api/contracts/auth'
@@ -249,7 +250,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
})
} catch (error) {
logger.error('Error fetching OIDC discovery document', {
error: error instanceof Error ? error.message : 'Unknown error',
error: getErrorMessage(error, 'Unknown error'),
discoveryUrl,
})
return NextResponse.json(
@@ -427,7 +428,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
} catch (error) {
logger.error('Failed to register SSO provider', {
error,
errorMessage: error instanceof Error ? error.message : 'Unknown error',
errorMessage: getErrorMessage(error, 'Unknown error'),
errorStack: error instanceof Error ? error.stack : undefined,
errorDetails: JSON.stringify(error),
})
@@ -435,7 +436,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
return NextResponse.json(
{
error: 'Failed to register SSO provider',
details: error instanceof Error ? error.message : 'Unknown error',
details: getErrorMessage(error, 'Unknown error'),
},
{ status: 500 }
)
@@ -1,7 +1,7 @@
import { db } from '@sim/db'
import { subscription as subscriptionTable } from '@sim/db/schema'
import { createLogger } from '@sim/logger'
import { toError } from '@sim/utils/errors'
import { getErrorMessage, toError } from '@sim/utils/errors'
import { eq } from 'drizzle-orm'
import { type NextRequest, NextResponse } from 'next/server'
import { billingSwitchPlanContract } from '@/lib/api/contracts/subscription'
@@ -181,7 +181,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
error: toError(error).message,
})
return NextResponse.json(
{ error: error instanceof Error ? error.message : 'Failed to switch plan' },
{ error: getErrorMessage(error, 'Failed to switch plan') },
{ status: 500 }
)
}
+1 -4
View File
@@ -2,6 +2,7 @@ import { AuditAction, AuditResourceType, recordAudit } from '@sim/audit'
import { db } from '@sim/db'
import { chat } from '@sim/db/schema'
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { and, eq, isNull } from 'drizzle-orm'
import type { NextRequest } from 'next/server'
import { chatIdParamsSchema, updateChatContract } from '@/lib/api/contracts/chats'
@@ -20,10 +21,6 @@ export const maxDuration = 120
const logger = createLogger('ChatDetailAPI')
function getErrorMessage(error: unknown, fallback: string): string {
return error instanceof Error ? error.message : fallback
}
/**
* GET endpoint to fetch a specific chat deployment by ID
*/
+1 -4
View File
@@ -1,6 +1,7 @@
import { db } from '@sim/db'
import { chat } from '@sim/db/schema'
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { and, eq, isNull } from 'drizzle-orm'
import type { NextRequest } from 'next/server'
import { createChatContract } from '@/lib/api/contracts/chats'
@@ -13,10 +14,6 @@ import { createErrorResponse, createSuccessResponse } from '@/app/api/workflows/
const logger = createLogger('ChatAPI')
function getErrorMessage(error: unknown, fallback: string): string {
return error instanceof Error ? error.message : fallback
}
export const GET = withRouteHandler(async (_request: NextRequest) => {
try {
const session = await getSession()
+4 -3
View File
@@ -1,4 +1,5 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { copilotChatAbortBodySchema } from '@/lib/api/contracts/copilot'
import { validationErrorResponse } from '@/lib/api/server'
@@ -36,7 +37,7 @@ export const POST = withRouteHandler((request: NextRequest) =>
const body = await request.json().catch((err) => {
logger.warn('Abort request body parse failed; continuing with empty object', {
error: err instanceof Error ? err.message : String(err),
error: getErrorMessage(err),
})
return {}
})
@@ -61,7 +62,7 @@ export const POST = withRouteHandler((request: NextRequest) =>
const run = await getLatestRunForStream(streamId, authenticatedUserId).catch((err) => {
logger.warn('getLatestRunForStream failed while resolving chatId for abort', {
streamId,
error: err instanceof Error ? err.message : String(err),
error: getErrorMessage(err),
})
return null
})
@@ -115,7 +116,7 @@ export const POST = withRouteHandler((request: NextRequest) =>
} catch (err) {
logger.warn('Explicit abort marker request failed after local abort', {
streamId,
error: err instanceof Error ? err.message : String(err),
error: getErrorMessage(err),
})
}
rootSpan.setAttribute(TraceAttr.CopilotAbortGoMarkerOk, goAbortOk)
@@ -1,5 +1,6 @@
import { type Context, context as otelContext, type Span, trace } from '@opentelemetry/api'
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { sleep } from '@sim/utils/helpers'
import { type NextRequest, NextResponse } from 'next/server'
import { copilotChatStreamContract } from '@/lib/api/contracts/copilot'
@@ -199,7 +200,7 @@ async function handleResumeRequestBody({
const run = await getLatestRunForStream(streamId, authenticatedUserId).catch((err) => {
logger.warn('Failed to fetch latest run for stream', {
streamId,
error: err instanceof Error ? err.message : String(err),
error: getErrorMessage(err),
})
return null
})
@@ -224,7 +225,7 @@ async function handleResumeRequestBody({
readFilePreviewSessions(streamId).catch((error) => {
logger.warn('Failed to read preview sessions for stream batch', {
streamId,
error: error instanceof Error ? error.message : String(error),
error: getErrorMessage(error),
})
return []
}),
@@ -395,7 +396,7 @@ async function handleResumeRequestBody({
(err) => {
logger.warn('Failed to poll latest run for stream', {
streamId,
error: err instanceof Error ? err.message : String(err),
error: getErrorMessage(err),
})
return null
}
@@ -452,7 +453,7 @@ async function handleResumeRequestBody({
if (!controllerClosed && !request.signal.aborted) {
logger.warn('Stream replay failed', {
streamId,
error: error instanceof Error ? error.message : String(error),
error: getErrorMessage(error),
})
emitTerminalIfMissing(MothershipStreamV1CompletionStatus.error, {
message: 'The stream replay failed before completion.',
+5 -7
View File
@@ -1,5 +1,5 @@
import { createLogger } from '@sim/logger'
import { toError } from '@sim/utils/errors'
import { getErrorMessage, toError } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { copilotConfirmContract } from '@/lib/api/contracts/copilot'
import { parseRequest, validationErrorResponse } from '@/lib/api/server'
@@ -150,7 +150,7 @@ export const POST = withRouteHandler((req: NextRequest) => {
const existing = await getAsyncToolCall(toolCallId).catch((err) => {
logger.warn('Failed to fetch async tool call', {
toolCallId,
error: err instanceof Error ? err.message : String(err),
error: getErrorMessage(err),
})
return null
})
@@ -165,7 +165,7 @@ export const POST = withRouteHandler((req: NextRequest) => {
const run = await getRunSegment(existing.runId).catch((err) => {
logger.warn('Failed to fetch run segment', {
runId: existing.runId,
error: err instanceof Error ? err.message : String(err),
error: getErrorMessage(err),
})
return null
})
@@ -205,14 +205,12 @@ export const POST = withRouteHandler((req: NextRequest) => {
logger.error(`[${tracker.requestId}] Unexpected error:`, {
duration,
error: error instanceof Error ? error.message : 'Unknown error',
error: getErrorMessage(error, 'Unknown error'),
stack: error instanceof Error ? error.stack : undefined,
})
span.setAttribute(TraceAttr.CopilotConfirmOutcome, CopilotConfirmOutcome.InternalError)
return createInternalServerErrorResponse(
error instanceof Error ? error.message : 'Internal server error'
)
return createInternalServerErrorResponse(getErrorMessage(error, 'Internal server error'))
}
}
)
@@ -1,3 +1,4 @@
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { copilotCredentialsContract } from '@/lib/api/contracts/copilot'
import { parseRequest } from '@/lib/api/server'
@@ -26,7 +27,7 @@ export const GET = withRouteHandler(async (req: NextRequest) => {
return NextResponse.json(
{
success: false,
error: error instanceof Error ? error.message : 'Failed to load credentials',
error: getErrorMessage(error, 'Failed to load credentials'),
},
{ status: 500 }
)
+2 -1
View File
@@ -1,6 +1,7 @@
import { db } from '@sim/db'
import { copilotFeedback } from '@sim/db/schema'
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { eq } from 'drizzle-orm'
import { type NextRequest, NextResponse } from 'next/server'
import { submitCopilotFeedbackContract } from '@/lib/api/contracts'
@@ -104,7 +105,7 @@ export const POST = withRouteHandler(async (req: NextRequest) => {
logger.error(`[${tracker.requestId}] Error submitting copilot feedback:`, {
duration,
error: error instanceof Error ? error.message : 'Unknown error',
error: getErrorMessage(error, 'Unknown error'),
stack: error instanceof Error ? error.stack : undefined,
})
@@ -1,4 +1,5 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { copilotTrainingExampleContract } from '@/lib/api/contracts/copilot'
import { parseRequest, validationErrorResponse } from '@/lib/api/server'
@@ -74,7 +75,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
headers: { 'content-type': 'application/json' },
})
} catch (err) {
const errorMessage = err instanceof Error ? err.message : 'Failed to add example'
const errorMessage = getErrorMessage(err, 'Failed to add example')
logger.error('Failed to send workflow example', { error: err })
return NextResponse.json({ error: errorMessage }, { status: 502 })
}
+2 -1
View File
@@ -1,4 +1,5 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { copilotTrainingDataContract } from '@/lib/api/contracts/copilot'
import { parseRequest, validationErrorResponse } from '@/lib/api/server'
@@ -85,7 +86,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
logger.error('Failed to send training data to agent indexer', { error })
return NextResponse.json(
{
error: error instanceof Error ? error.message : 'Failed to send training data',
error: getErrorMessage(error, 'Failed to send training data'),
},
{ status: 502 }
)
@@ -2,6 +2,7 @@ import { AuditAction, AuditResourceType, recordAudit } from '@sim/audit'
import { db } from '@sim/db'
import { credentialSet, credentialSetMember, organization } from '@sim/db/schema'
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { generateId } from '@sim/utils/id'
import { and, eq } from 'drizzle-orm'
import { type NextRequest, NextResponse } from 'next/server'
@@ -132,7 +133,7 @@ export const DELETE = withRouteHandler(async (req: NextRequest) => {
return NextResponse.json({ success: true })
} catch (error) {
const message = error instanceof Error ? error.message : 'Failed to leave credential set'
const message = getErrorMessage(error, 'Failed to leave credential set')
logger.error('Error leaving credential set', error)
return NextResponse.json({ error: message }, { status: 500 })
}
+2 -1
View File
@@ -1,4 +1,5 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import {
abortMultipartUploadContract,
@@ -438,7 +439,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
} catch (error) {
logger.error('Multipart upload error:', error)
return NextResponse.json(
{ error: error instanceof Error ? error.message : 'Multipart upload failed' },
{ error: getErrorMessage(error, 'Multipart upload failed') },
{ status: 500 }
)
}
+4 -2
View File
@@ -3,6 +3,8 @@ import { createHash } from 'crypto'
import fsPromises, { readFile } from 'fs/promises'
import path from 'path'
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { generateShortId } from '@sim/utils/id'
import binaryExtensionsList from 'binary-extensions'
import { type NextRequest, NextResponse } from 'next/server'
import { fileParseContract } from '@/lib/api/contracts/storage-transfer'
@@ -218,7 +220,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
return NextResponse.json(
{
success: false,
error: error instanceof Error ? error.message : 'Unknown error occurred',
error: getErrorMessage(error, 'Unknown error occurred'),
filePath: '',
},
{ status: 500 }
@@ -552,7 +554,7 @@ async function handleCloudFile(
// If file is already from execution context, create UserFile reference without re-uploading
if (context === 'execution') {
userFile = {
id: `file_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`,
id: `file_${Date.now()}_${generateShortId(7)}`,
name: filename,
url: normalizedFilePath,
size: fileBuffer.length,
+2 -3
View File
@@ -1,4 +1,5 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { presignedUploadBodyContract, uploadTypeSchema } from '@/lib/api/contracts/storage-transfer'
import { getValidationErrorMessage, parseRequest } from '@/lib/api/server'
@@ -124,9 +125,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
expirationSeconds: 3600,
})
} catch (error) {
throw new ValidationError(
error instanceof Error ? error.message : 'Copilot validation failed'
)
throw new ValidationError(getErrorMessage(error, 'Copilot validation failed'))
}
} else if (uploadType === 'mothership') {
const workspaceId = request.nextUrl.searchParams.get('workspaceId')
+2 -2
View File
@@ -1,4 +1,5 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { sanitizeFileName } from '@/executor/constants'
import '@/lib/uploads/core/setup.server'
@@ -218,8 +219,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
uploadResults.push(userFile)
continue
} catch (workspaceError) {
const errorMessage =
workspaceError instanceof Error ? workspaceError.message : 'Upload failed'
const errorMessage = getErrorMessage(workspaceError, 'Upload failed')
const isDuplicate = errorMessage.includes('already exists')
const isStorageLimitError =
errorMessage.includes('Storage limit exceeded') ||
@@ -1,4 +1,5 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { restoreFolderContract } from '@/lib/api/contracts'
import { parseRequest } from '@/lib/api/server'
@@ -52,7 +53,7 @@ export const POST = withRouteHandler(async (request: NextRequest, context: Route
} catch (error) {
logger.error('Error restoring folder', error)
return NextResponse.json(
{ error: error instanceof Error ? error.message : 'Internal server error' },
{ error: getErrorMessage(error, 'Internal server error') },
{ status: 500 }
)
}
+1 -4
View File
@@ -2,6 +2,7 @@ import { AuditAction, AuditResourceType, recordAudit } from '@sim/audit'
import { db } from '@sim/db'
import { form } from '@sim/db/schema'
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { and, eq, isNull } from 'drizzle-orm'
import type { NextRequest } from 'next/server'
import { formIdParamsSchema, updateFormContract } from '@/lib/api/contracts/forms'
@@ -14,10 +15,6 @@ import { createErrorResponse, createSuccessResponse } from '@/app/api/workflows/
const logger = createLogger('FormManageAPI')
function getErrorMessage(error: unknown, fallback: string): string {
return error instanceof Error ? error.message : fallback
}
export const GET = withRouteHandler(
async (request: NextRequest, { params }: { params: Promise<{ id: string }> }) => {
try {
+1 -4
View File
@@ -2,6 +2,7 @@ import { AuditAction, AuditResourceType, recordAudit } from '@sim/audit'
import { db } from '@sim/db'
import { form } from '@sim/db/schema'
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { generateId } from '@sim/utils/id'
import { and, eq, isNull } from 'drizzle-orm'
import type { NextRequest } from 'next/server'
@@ -22,10 +23,6 @@ import { createErrorResponse, createSuccessResponse } from '@/app/api/workflows/
const logger = createLogger('FormAPI')
export const maxDuration = 120
function getErrorMessage(error: unknown, fallback: string): string {
return error instanceof Error ? error.message : fallback
}
async function cleanupFormAfterDeployFailure(formId: string) {
try {
await db.delete(form).where(eq(form.id, formId))
+2 -1
View File
@@ -1,6 +1,7 @@
import { db } from '@sim/db'
import { form } from '@sim/db/schema'
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { and, eq, isNull } from 'drizzle-orm'
import type { NextRequest } from 'next/server'
import { formIdentifierValidationQuerySchema } from '@/lib/api/contracts/forms'
@@ -58,7 +59,7 @@ export const GET = withRouteHandler(async (request: NextRequest) => {
error: isAvailable ? null : 'This identifier is already in use',
})
} catch (error: unknown) {
const message = error instanceof Error ? error.message : 'Failed to validate identifier'
const message = getErrorMessage(error, 'Failed to validate identifier')
logger.error('Error validating form identifier:', error)
return createErrorResponse(message, 500)
}
@@ -1,4 +1,5 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { authorizeWorkflowByWorkspacePermission } from '@sim/workflow-authz'
import { type NextRequest, NextResponse } from 'next/server'
import {
@@ -212,7 +213,7 @@ export const POST = withRouteHandler(
)
} catch (error) {
logger.warn(`[${requestId}] Failed to calculate cost for chunk upload`, {
error: error instanceof Error ? error.message : 'Unknown error',
error: getErrorMessage(error, 'Unknown error'),
})
// Continue without cost information rather than failing the upload
}
@@ -1,5 +1,6 @@
import { AuditAction, AuditResourceType, recordAudit } from '@sim/audit'
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { generateId } from '@sim/utils/id'
import { authorizeWorkflowByWorkspacePermission } from '@sim/workflow-authz'
import { type NextRequest, NextResponse } from 'next/server'
@@ -301,7 +302,7 @@ export const POST = withRouteHandler(
} catch (error) {
logger.error(`[${requestId}] Error creating document`, error)
const errorMessage = error instanceof Error ? error.message : 'Failed to create document'
const errorMessage = getErrorMessage(error, 'Failed to create document')
const isStorageLimitError =
errorMessage.includes('Storage limit exceeded') || errorMessage.includes('storage limit')
const isMissingKnowledgeBase = errorMessage === 'Knowledge base not found'
@@ -2,6 +2,7 @@ import { AuditAction, AuditResourceType, recordAudit } from '@sim/audit'
import { db } from '@sim/db'
import { document } from '@sim/db/schema'
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { generateId } from '@sim/utils/id'
import { authorizeWorkflowByWorkspacePermission } from '@sim/workflow-authz'
import { and, eq, isNull } from 'drizzle-orm'
@@ -218,7 +219,7 @@ export const POST = withRouteHandler(
} catch (error) {
logger.error(`[${requestId}] Error upserting document`, error)
const errorMessage = error instanceof Error ? error.message : 'Failed to upsert document'
const errorMessage = getErrorMessage(error, 'Failed to upsert document')
const isStorageLimitError =
errorMessage.includes('Storage limit exceeded') || errorMessage.includes('storage limit')
const isMissingKnowledgeBase = errorMessage === 'Knowledge base not found'
@@ -1,4 +1,5 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { restoreKnowledgeBaseContract } from '@/lib/api/contracts/knowledge'
import { parseRequest } from '@/lib/api/server'
@@ -58,7 +59,7 @@ export const POST = withRouteHandler(
} catch (error) {
logger.error(`[${requestId}] Error restoring knowledge base ${id}`, error)
return NextResponse.json(
{ error: error instanceof Error ? error.message : 'Internal server error' },
{ error: getErrorMessage(error, 'Internal server error') },
{ status: 500 }
)
}
+4 -3
View File
@@ -1,4 +1,5 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { authorizeWorkflowByWorkspacePermission } from '@sim/workflow-authz'
import { type NextRequest, NextResponse } from 'next/server'
import { knowledgeSearchBodySchema } from '@/lib/api/contracts/knowledge'
@@ -339,7 +340,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
}
} catch (error) {
logger.warn(`[${requestId}] Reranker failed; falling back to vector ordering`, {
error: error instanceof Error ? error.message : 'Unknown error',
error: getErrorMessage(error, 'Unknown error'),
model: rerankerModel,
candidateCount,
workspaceId,
@@ -361,7 +362,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
cost = calculateCost(queryEmbeddingModel, tokenCount.count, 0, false)
} catch (error) {
logger.warn(`[${requestId}] Failed to calculate cost for search query`, {
error: error instanceof Error ? error.message : 'Unknown error',
error: getErrorMessage(error, 'Unknown error'),
})
}
}
@@ -491,7 +492,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
return NextResponse.json(
{
error: 'Failed to perform vector search',
message: error instanceof Error ? error.message : 'Unknown error',
message: getErrorMessage(error, 'Unknown error'),
},
{ status: 500 }
)
+3 -3
View File
@@ -1,5 +1,5 @@
import { createLogger } from '@sim/logger'
import { toError } from '@sim/utils/errors'
import { getErrorMessage, toError } from '@sim/utils/errors'
import { generateId } from '@sim/utils/id'
import { type NextRequest, NextResponse } from 'next/server'
import { mothershipExecuteContract } from '@/lib/api/contracts/mothership-tasks'
@@ -207,12 +207,12 @@ export const POST = withRouteHandler(async (req: NextRequest) => {
messageId ? `Mothership execute error [messageId:${messageId}]` : 'Mothership execute error',
{
requestId,
error: error instanceof Error ? error.message : 'Unknown error',
error: getErrorMessage(error, 'Unknown error'),
}
)
return NextResponse.json(
{ error: error instanceof Error ? error.message : 'Internal server error' },
{ error: getErrorMessage(error, 'Internal server error') },
{ status: 500 }
)
}
+2 -1
View File
@@ -1,4 +1,5 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { generateShortId } from '@sim/utils/id'
import { type NextRequest, NextResponse } from 'next/server'
import { noInputSchema } from '@/lib/api/contracts/primitives'
@@ -60,7 +61,7 @@ export const GET = withRouteHandler(async (request: NextRequest) => {
{
success: false,
message: 'Inactivity alert polling failed',
error: error instanceof Error ? error.message : 'Unknown error',
error: getErrorMessage(error, 'Unknown error'),
requestId,
},
{ status: 500 }
+5 -4
View File
@@ -2,6 +2,7 @@ import { AuditAction, AuditResourceType, recordAudit } from '@sim/audit'
import { db } from '@sim/db'
import { member, organization, subscription as subscriptionTable } from '@sim/db/schema'
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { and, eq, inArray, or } from 'drizzle-orm'
import type { NextRequest } from 'next/server'
import { NextResponse } from 'next/server'
@@ -66,7 +67,7 @@ export const GET = withRouteHandler(async (request: NextRequest) => {
})
} catch (error) {
logger.error('Failed to fetch organizations', {
error: error instanceof Error ? error.message : 'Unknown error',
error: getErrorMessage(error, 'Unknown error'),
stack: error instanceof Error ? error.stack : undefined,
})
@@ -230,7 +231,7 @@ export const POST = withRouteHandler(async (request: Request) => {
logger.error('Failed to activate organization after creation', {
organizationId,
userId: user.id,
error: error instanceof Error ? error.message : String(error),
error: getErrorMessage(error),
})
}
@@ -287,14 +288,14 @@ export const POST = withRouteHandler(async (request: Request) => {
}
logger.error('Failed to create organization for team plan', {
error: error instanceof Error ? error.message : 'Unknown error',
error: getErrorMessage(error, 'Unknown error'),
stack: error instanceof Error ? error.stack : undefined,
})
return NextResponse.json(
{
error: 'Failed to create organization',
message: error instanceof Error ? error.message : 'Unknown error',
message: getErrorMessage(error, 'Unknown error'),
},
{ status: 500 }
)
@@ -1,4 +1,5 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import {
fireworksProviderModelsQuerySchema,
@@ -99,7 +100,7 @@ export const GET = withRouteHandler(async (request: NextRequest) => {
return NextResponse.json(providerModelsResponseSchema.parse({ models }))
} catch (error) {
logger.error('Error fetching Fireworks models', {
error: error instanceof Error ? error.message : 'Unknown error',
error: getErrorMessage(error, 'Unknown error'),
})
return NextResponse.json({ models: [] })
}
@@ -1,4 +1,5 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import {
ollamaUpstreamResponseSchema,
@@ -53,7 +54,7 @@ export const GET = withRouteHandler(async (_request: NextRequest) => {
return NextResponse.json(providerModelsResponseSchema.parse({ models }))
} catch (error) {
logger.error('Failed to fetch Ollama models', {
error: error instanceof Error ? error.message : 'Unknown error',
error: getErrorMessage(error, 'Unknown error'),
host: OLLAMA_HOST,
})
@@ -1,4 +1,5 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import {
openRouterUpstreamResponseSchema,
@@ -94,7 +95,7 @@ export const GET = withRouteHandler(async (_request: NextRequest) => {
return NextResponse.json(providerModelsResponseSchema.parse({ models, modelInfo }))
} catch (error) {
logger.error('Error fetching OpenRouter models', {
error: error instanceof Error ? error.message : 'Unknown error',
error: getErrorMessage(error, 'Unknown error'),
})
return NextResponse.json({ models: [], modelInfo: {} })
}
+2 -2
View File
@@ -1,7 +1,7 @@
import { db } from '@sim/db'
import { account } from '@sim/db/schema'
import { createLogger } from '@sim/logger'
import { toError } from '@sim/utils/errors'
import { getErrorMessage, toError } from '@sim/utils/errors'
import { eq } from 'drizzle-orm'
import { type NextRequest, NextResponse } from 'next/server'
import { executeProviderContract } from '@/lib/api/contracts/providers'
@@ -167,7 +167,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
hasVertexCredential: !!vertexCredential,
})
return NextResponse.json(
{ error: error instanceof Error ? error.message : 'Credential error' },
{ error: getErrorMessage(error, 'Credential error') },
{ status: 400 }
)
}
@@ -1,4 +1,5 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import {
providerModelsResponseSchema,
@@ -65,7 +66,7 @@ export const GET = withRouteHandler(async (_request: NextRequest) => {
return NextResponse.json(providerModelsResponseSchema.parse({ models }))
} catch (error) {
logger.error('Failed to fetch vLLM models', {
error: error instanceof Error ? error.message : 'Unknown error',
error: getErrorMessage(error, 'Unknown error'),
baseUrl,
})
+2 -1
View File
@@ -1,4 +1,5 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { importSkillContract } from '@/lib/api/contracts'
import { parseRequest } from '@/lib/api/server'
@@ -58,7 +59,7 @@ export const POST = withRouteHandler(async (req: NextRequest) => {
try {
rawUrl = toRawGitHubUrl(url)
} catch (err) {
const message = err instanceof Error ? err.message : 'Invalid URL'
const message = getErrorMessage(err, 'Invalid URL')
return NextResponse.json({ error: message }, { status: 400 })
}
+2 -1
View File
@@ -1,6 +1,7 @@
import { db } from '@sim/db'
import { chat } from '@sim/db/schema'
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { eq } from 'drizzle-orm'
import { type NextRequest, NextResponse } from 'next/server'
import { speechTokenBodySchema } from '@/lib/api/contracts/media/speech'
@@ -171,7 +172,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
return NextResponse.json({ token: data.token })
} catch (error) {
const message = error instanceof Error ? error.message : 'Failed to generate speech token'
const message = getErrorMessage(error, 'Failed to generate speech token')
logger.error('Speech token error:', error)
return NextResponse.json({ error: message }, { status: 500 })
}
@@ -1,4 +1,5 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { tableIdParamsSchema } from '@/lib/api/contracts/tables'
import { checkSessionOrInternalAuth } from '@/lib/auth/hybrid'
@@ -47,7 +48,7 @@ export const POST = withRouteHandler(
} catch (error) {
logger.error(`[${requestId}] Error restoring table ${tableId}`, error)
return NextResponse.json(
{ error: error instanceof Error ? error.message : 'Internal server error' },
{ error: getErrorMessage(error, 'Internal server error') },
{ status: 500 }
)
}
+2 -1
View File
@@ -1,4 +1,5 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { getTableQuerySchema, renameTableContract } from '@/lib/api/contracts/tables'
import { isZodError, parseRequest, validationErrorResponse } from '@/lib/api/server/validation'
@@ -127,7 +128,7 @@ export const PATCH = withRouteHandler(
logger.error(`[${requestId}] Error renaming table:`, error)
return NextResponse.json(
{ error: error instanceof Error ? error.message : 'Failed to rename table' },
{ error: getErrorMessage(error, 'Failed to rename table') },
{ status: 500 }
)
}
@@ -1,5 +1,5 @@
import { createLogger } from '@sim/logger'
import { toError } from '@sim/utils/errors'
import { getErrorMessage, toError } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { asanaCreateTaskContract } from '@/lib/api/contracts/tools/asana'
import { parseRequest } from '@/lib/api/server'
@@ -112,7 +112,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
return NextResponse.json(
{
error: error instanceof Error ? error.message : 'Internal server error',
error: getErrorMessage(error, 'Internal server error'),
success: false,
},
{ status: 500 }
@@ -1,5 +1,5 @@
import { createLogger } from '@sim/logger'
import { toError } from '@sim/utils/errors'
import { getErrorMessage, toError } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { asanaUpdateTaskContract } from '@/lib/api/contracts/tools/asana'
import { parseRequest } from '@/lib/api/server'
@@ -116,7 +116,7 @@ export const PUT = withRouteHandler(async (request: NextRequest) => {
return NextResponse.json(
{
error: error instanceof Error ? error.message : 'Internal server error',
error: getErrorMessage(error, 'Internal server error'),
success: false,
},
{ status: 500 }
@@ -1,5 +1,6 @@
import { CreateNamedQueryCommand } from '@aws-sdk/client-athena'
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { awsAthenaCreateNamedQueryContract } from '@/lib/api/contracts/tools/aws/athena-create-named-query'
import { parseToolRequest } from '@/lib/api/server'
@@ -50,8 +51,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
},
})
} catch (error) {
const errorMessage =
error instanceof Error ? error.message : 'Failed to create Athena named query'
const errorMessage = getErrorMessage(error, 'Failed to create Athena named query')
logger.error('CreateNamedQuery failed', { error: errorMessage })
return NextResponse.json({ error: errorMessage }, { status: 500 })
}
@@ -1,5 +1,6 @@
import { GetNamedQueryCommand } from '@aws-sdk/client-athena'
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { awsAthenaGetNamedQueryContract } from '@/lib/api/contracts/tools/aws/athena-get-named-query'
import { parseToolRequest } from '@/lib/api/server'
@@ -52,7 +53,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
},
})
} catch (error) {
const errorMessage = error instanceof Error ? error.message : 'Failed to get Athena named query'
const errorMessage = getErrorMessage(error, 'Failed to get Athena named query')
logger.error('GetNamedQuery failed', { error: errorMessage })
return NextResponse.json({ error: errorMessage }, { status: 500 })
}
@@ -1,5 +1,6 @@
import { GetQueryExecutionCommand } from '@aws-sdk/client-athena'
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { awsAthenaGetQueryExecutionContract } from '@/lib/api/contracts/tools/aws/athena-get-query-execution'
import { parseToolRequest } from '@/lib/api/server'
@@ -62,8 +63,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
},
})
} catch (error) {
const errorMessage =
error instanceof Error ? error.message : 'Failed to get Athena query execution'
const errorMessage = getErrorMessage(error, 'Failed to get Athena query execution')
logger.error('GetQueryExecution failed', { error: errorMessage })
return NextResponse.json({ error: errorMessage }, { status: 500 })
}
@@ -1,5 +1,6 @@
import { GetQueryResultsCommand } from '@aws-sdk/client-athena'
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { awsAthenaGetQueryResultsContract } from '@/lib/api/contracts/tools/aws/athena-get-query-results'
import { parseToolRequest } from '@/lib/api/server'
@@ -68,8 +69,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
},
})
} catch (error) {
const errorMessage =
error instanceof Error ? error.message : 'Failed to get Athena query results'
const errorMessage = getErrorMessage(error, 'Failed to get Athena query results')
logger.error('GetQueryResults failed', { error: errorMessage })
return NextResponse.json({ error: errorMessage }, { status: 500 })
}
@@ -1,5 +1,6 @@
import { ListNamedQueriesCommand } from '@aws-sdk/client-athena'
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { awsAthenaListNamedQueriesContract } from '@/lib/api/contracts/tools/aws/athena-list-named-queries'
import { parseToolRequest } from '@/lib/api/server'
@@ -45,8 +46,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
},
})
} catch (error) {
const errorMessage =
error instanceof Error ? error.message : 'Failed to list Athena named queries'
const errorMessage = getErrorMessage(error, 'Failed to list Athena named queries')
logger.error('ListNamedQueries failed', { error: errorMessage })
return NextResponse.json({ error: errorMessage }, { status: 500 })
}
@@ -1,5 +1,6 @@
import { ListQueryExecutionsCommand } from '@aws-sdk/client-athena'
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { awsAthenaListQueryExecutionsContract } from '@/lib/api/contracts/tools/aws/athena-list-query-executions'
import { parseToolRequest } from '@/lib/api/server'
@@ -45,8 +46,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
},
})
} catch (error) {
const errorMessage =
error instanceof Error ? error.message : 'Failed to list Athena query executions'
const errorMessage = getErrorMessage(error, 'Failed to list Athena query executions')
logger.error('ListQueryExecutions failed', { error: errorMessage })
return NextResponse.json({ error: errorMessage }, { status: 500 })
}
@@ -1,5 +1,6 @@
import { StartQueryExecutionCommand } from '@aws-sdk/client-athena'
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { awsAthenaStartQueryContract } from '@/lib/api/contracts/tools/aws/athena-start-query'
import { parseToolRequest } from '@/lib/api/server'
@@ -62,7 +63,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
},
})
} catch (error) {
const errorMessage = error instanceof Error ? error.message : 'Failed to start Athena query'
const errorMessage = getErrorMessage(error, 'Failed to start Athena query')
logger.error('StartQuery failed', { error: errorMessage })
return NextResponse.json({ error: errorMessage }, { status: 500 })
}
@@ -1,5 +1,6 @@
import { StopQueryExecutionCommand } from '@aws-sdk/client-athena'
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { awsAthenaStopQueryContract } from '@/lib/api/contracts/tools/aws/athena-stop-query'
import { parseToolRequest } from '@/lib/api/server'
@@ -42,7 +43,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
},
})
} catch (error) {
const errorMessage = error instanceof Error ? error.message : 'Failed to stop Athena query'
const errorMessage = getErrorMessage(error, 'Failed to stop Athena query')
logger.error('StopQuery failed', { error: errorMessage })
return NextResponse.json({ error: errorMessage }, { status: 500 })
}
+2 -1
View File
@@ -1,4 +1,5 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { boxUploadContract } from '@/lib/api/contracts/storage-transfer'
import { parseRequest } from '@/lib/api/server'
@@ -122,7 +123,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
} catch (error) {
logger.error(`[${requestId}] Unexpected error:`, error)
return NextResponse.json(
{ success: false, error: error instanceof Error ? error.message : 'Unknown error' },
{ success: false, error: getErrorMessage(error, 'Unknown error') },
{ status: 500 }
)
}
@@ -3,6 +3,7 @@ import {
DescribeStackDriftDetectionStatusCommand,
} from '@aws-sdk/client-cloudformation'
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { awsCloudformationDescribeStackDriftDetectionStatusContract } from '@/lib/api/contracts/tools/aws/cloudformation-describe-stack-drift-detection-status'
import { parseToolRequest } from '@/lib/api/server'
@@ -56,8 +57,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
},
})
} catch (error) {
const errorMessage =
error instanceof Error ? error.message : 'Failed to describe stack drift detection status'
const errorMessage = getErrorMessage(error, 'Failed to describe stack drift detection status')
logger.error('DescribeStackDriftDetectionStatus failed', { error: errorMessage })
return NextResponse.json({ error: errorMessage }, { status: 500 })
}
@@ -4,6 +4,7 @@ import {
type StackEvent,
} from '@aws-sdk/client-cloudformation'
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { awsCloudformationDescribeStackEventsContract } from '@/lib/api/contracts/tools/aws/cloudformation-describe-stack-events'
import { parseToolRequest } from '@/lib/api/server'
@@ -65,8 +66,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
output: { events },
})
} catch (error) {
const errorMessage =
error instanceof Error ? error.message : 'Failed to describe CloudFormation stack events'
const errorMessage = getErrorMessage(error, 'Failed to describe CloudFormation stack events')
logger.error('DescribeStackEvents failed', { error: errorMessage })
return NextResponse.json({ error: errorMessage }, { status: 500 })
}
@@ -4,6 +4,7 @@ import {
type Stack,
} from '@aws-sdk/client-cloudformation'
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { awsCloudformationDescribeStacksContract } from '@/lib/api/contracts/tools/aws/cloudformation-describe-stacks'
import { parseToolRequest } from '@/lib/api/server'
@@ -77,8 +78,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
output: { stacks },
})
} catch (error) {
const errorMessage =
error instanceof Error ? error.message : 'Failed to describe CloudFormation stacks'
const errorMessage = getErrorMessage(error, 'Failed to describe CloudFormation stacks')
logger.error('DescribeStacks failed', { error: errorMessage })
return NextResponse.json({ error: errorMessage }, { status: 500 })
}
@@ -1,5 +1,6 @@
import { CloudFormationClient, DetectStackDriftCommand } from '@aws-sdk/client-cloudformation'
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { awsCloudformationDetectStackDriftContract } from '@/lib/api/contracts/tools/aws/cloudformation-detect-stack-drift'
import { parseToolRequest } from '@/lib/api/server'
@@ -47,8 +48,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
},
})
} catch (error) {
const errorMessage =
error instanceof Error ? error.message : 'Failed to detect CloudFormation stack drift'
const errorMessage = getErrorMessage(error, 'Failed to detect CloudFormation stack drift')
logger.error('DetectStackDrift failed', { error: errorMessage })
return NextResponse.json({ error: errorMessage }, { status: 500 })
}
@@ -1,5 +1,6 @@
import { CloudFormationClient, GetTemplateCommand } from '@aws-sdk/client-cloudformation'
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { awsCloudformationGetTemplateContract } from '@/lib/api/contracts/tools/aws/cloudformation-get-template'
import { parseToolRequest } from '@/lib/api/server'
@@ -44,8 +45,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
},
})
} catch (error) {
const errorMessage =
error instanceof Error ? error.message : 'Failed to get CloudFormation template'
const errorMessage = getErrorMessage(error, 'Failed to get CloudFormation template')
logger.error('GetTemplate failed', { error: errorMessage })
return NextResponse.json({ error: errorMessage }, { status: 500 })
}
@@ -4,6 +4,7 @@ import {
type StackResourceSummary,
} from '@aws-sdk/client-cloudformation'
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { awsCloudformationListStackResourcesContract } from '@/lib/api/contracts/tools/aws/cloudformation-list-stack-resources'
import { parseToolRequest } from '@/lib/api/server'
@@ -66,8 +67,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
output: { resources },
})
} catch (error) {
const errorMessage =
error instanceof Error ? error.message : 'Failed to list CloudFormation stack resources'
const errorMessage = getErrorMessage(error, 'Failed to list CloudFormation stack resources')
logger.error('ListStackResources failed', { error: errorMessage })
return NextResponse.json({ error: errorMessage }, { status: 500 })
}
@@ -1,5 +1,6 @@
import { CloudFormationClient, ValidateTemplateCommand } from '@aws-sdk/client-cloudformation'
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { awsCloudformationValidateTemplateContract } from '@/lib/api/contracts/tools/aws/cloudformation-validate-template'
import { parseToolRequest } from '@/lib/api/server'
@@ -52,8 +53,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
},
})
} catch (error) {
const errorMessage =
error instanceof Error ? error.message : 'Failed to validate CloudFormation template'
const errorMessage = getErrorMessage(error, 'Failed to validate CloudFormation template')
logger.error('ValidateTemplate failed', { error: errorMessage })
return NextResponse.json({ error: errorMessage }, { status: 500 })
}
@@ -1,4 +1,5 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { confluenceUploadAttachmentContract } from '@/lib/api/contracts/selectors/confluence'
import { parseRequest } from '@/lib/api/server'
@@ -76,7 +77,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
userFile = processSingleFileToUserFile(fileToProcess, 'confluence-upload', logger)
} catch (error) {
return NextResponse.json(
{ error: error instanceof Error ? error.message : 'Failed to process file' },
{ error: getErrorMessage(error, 'Failed to process file') },
{ status: 400 }
)
}
@@ -96,7 +97,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
logger.error('Failed to download file from storage:', error)
return NextResponse.json(
{
error: `Failed to download file: ${error instanceof Error ? error.message : 'Unknown error'}`,
error: `Failed to download file: ${getErrorMessage(error, 'Unknown error')}`,
},
{ status: 500 }
)
@@ -1,4 +1,5 @@
import { createLogger } from '@sim/logger'
import { toError } from '@sim/utils/errors'
import { generateId } from '@sim/utils/id'
import { type NextRequest, NextResponse } from 'next/server'
import { crowdstrikeQueryContract } from '@/lib/api/contracts/tools/crowdstrike'
@@ -405,7 +406,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
output: normalizeAggregatesOutput(aggregateData),
})
} catch (error) {
const message = error instanceof Error ? error.message : 'Unknown error'
const message = toError(error).message
logger.error(`[${requestId}] CrowdStrike request failed`, { error: message })
return NextResponse.json({ success: false, error: message }, { status: 500 })
}
@@ -1,4 +1,5 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { cursorDownloadArtifactContract } from '@/lib/api/contracts/tools/cursor'
import { getValidationErrorMessage, parseRequest } from '@/lib/api/server'
@@ -151,7 +152,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
} catch (error) {
logger.error(`[${requestId}] Error downloading Cursor artifact:`, error)
return NextResponse.json(
{ success: false, error: error instanceof Error ? error.message : 'Unknown error occurred' },
{ success: false, error: getErrorMessage(error, 'Unknown error occurred') },
{ status: 500 }
)
}
+2 -1
View File
@@ -2,6 +2,7 @@ import { AuditAction, AuditResourceType, recordAudit } from '@sim/audit'
import { db } from '@sim/db'
import { customTools } from '@sim/db/schema'
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { authorizeWorkflowByWorkspacePermission } from '@sim/workflow-authz'
import { and, desc, eq, isNull, or } from 'drizzle-orm'
import { type NextRequest, NextResponse } from 'next/server'
@@ -182,7 +183,7 @@ export const POST = withRouteHandler(async (req: NextRequest) => {
return NextResponse.json({ success: true, data: resultTools })
} catch (error) {
logger.error(`[${requestId}] Error updating custom tools`, error)
const errorMessage = error instanceof Error ? error.message : 'Failed to update custom tools'
const errorMessage = getErrorMessage(error, 'Failed to update custom tools')
return NextResponse.json({ error: errorMessage }, { status: 500 })
}
})
@@ -1,4 +1,5 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { discordSendMessageContract } from '@/lib/api/contracts/tools/communication/discord'
import { parseRequest } from '@/lib/api/server'
@@ -150,7 +151,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
} catch (error) {
logger.error(`[${requestId}] Failed to download attachment ${file.name}:`, error)
throw new Error(
`Failed to download attachment "${file.name}": ${error instanceof Error ? error.message : 'Unknown error'}`
`Failed to download attachment "${file.name}": ${getErrorMessage(error, 'Unknown error')}`
)
}
})
@@ -208,7 +209,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
return NextResponse.json(
{
success: false,
error: error instanceof Error ? error.message : 'Unknown error occurred',
error: getErrorMessage(error, 'Unknown error occurred'),
},
{ status: 500 }
)
+2 -1
View File
@@ -1,4 +1,5 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { docusignToolContract } from '@/lib/api/contracts/tools/docusign'
import { getValidationErrorMessage, parseRequest } from '@/lib/api/server'
@@ -108,7 +109,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
}
} catch (error) {
logger.error('DocuSign API error', { operation, error })
const message = error instanceof Error ? error.message : 'Internal server error'
const message = getErrorMessage(error, 'Internal server error')
return NextResponse.json({ success: false, error: message }, { status: 500 })
}
})
@@ -1,4 +1,5 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { dropboxUploadContract } from '@/lib/api/contracts/storage-transfer'
import { parseRequest } from '@/lib/api/server'
@@ -110,7 +111,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
} catch (error) {
logger.error(`[${requestId}] Unexpected error:`, error)
return NextResponse.json(
{ success: false, error: error instanceof Error ? error.message : 'Unknown error' },
{ success: false, error: getErrorMessage(error, 'Unknown error') },
{ status: 500 }
)
}
@@ -1,4 +1,5 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { evernoteCopyNoteContract } from '@/lib/api/contracts/tools/evernote'
import { getValidationErrorMessage, parseRequest } from '@/lib/api/server'
@@ -41,7 +42,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
output: { note },
})
} catch (error) {
const message = error instanceof Error ? error.message : 'Unknown error'
const message = getErrorMessage(error, 'Unknown error')
logger.error('Failed to copy note', { error: message })
return NextResponse.json({ success: false, error: message }, { status: 500 })
}
@@ -1,4 +1,5 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { evernoteCreateNoteContract } from '@/lib/api/contracts/tools/evernote'
import { getValidationErrorMessage, parseRequest } from '@/lib/api/server'
@@ -54,7 +55,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
output: { note },
})
} catch (error) {
const message = error instanceof Error ? error.message : 'Unknown error'
const message = getErrorMessage(error, 'Unknown error')
logger.error('Failed to create note', { error: message })
return NextResponse.json({ success: false, error: message }, { status: 500 })
}
@@ -1,4 +1,5 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { evernoteCreateNotebookContract } from '@/lib/api/contracts/tools/evernote'
import { getValidationErrorMessage, parseRequest } from '@/lib/api/server'
@@ -41,7 +42,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
output: { notebook },
})
} catch (error) {
const message = error instanceof Error ? error.message : 'Unknown error'
const message = getErrorMessage(error, 'Unknown error')
logger.error('Failed to create notebook', { error: message })
return NextResponse.json({ success: false, error: message }, { status: 500 })
}
@@ -1,4 +1,5 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { evernoteCreateTagContract } from '@/lib/api/contracts/tools/evernote'
import { getValidationErrorMessage, parseRequest } from '@/lib/api/server'
@@ -41,7 +42,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
output: { tag },
})
} catch (error) {
const message = error instanceof Error ? error.message : 'Unknown error'
const message = getErrorMessage(error, 'Unknown error')
logger.error('Failed to create tag', { error: message })
return NextResponse.json({ success: false, error: message }, { status: 500 })
}
@@ -1,4 +1,5 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { evernoteDeleteNoteContract } from '@/lib/api/contracts/tools/evernote'
import { getValidationErrorMessage, parseRequest } from '@/lib/api/server'
@@ -44,7 +45,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
},
})
} catch (error) {
const message = error instanceof Error ? error.message : 'Unknown error'
const message = getErrorMessage(error, 'Unknown error')
logger.error('Failed to delete note', { error: message })
return NextResponse.json({ success: false, error: message }, { status: 500 })
}
@@ -1,4 +1,5 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { evernoteGetNoteContract } from '@/lib/api/contracts/tools/evernote'
import { getValidationErrorMessage, parseRequest } from '@/lib/api/server'
@@ -41,7 +42,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
output: { note },
})
} catch (error) {
const message = error instanceof Error ? error.message : 'Unknown error'
const message = getErrorMessage(error, 'Unknown error')
logger.error('Failed to get note', { error: message })
return NextResponse.json({ success: false, error: message }, { status: 500 })
}
@@ -1,4 +1,5 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { evernoteGetNotebookContract } from '@/lib/api/contracts/tools/evernote'
import { getValidationErrorMessage, parseRequest } from '@/lib/api/server'
@@ -41,7 +42,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
output: { notebook },
})
} catch (error) {
const message = error instanceof Error ? error.message : 'Unknown error'
const message = getErrorMessage(error, 'Unknown error')
logger.error('Failed to get notebook', { error: message })
return NextResponse.json({ success: false, error: message }, { status: 500 })
}
@@ -1,4 +1,5 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { evernoteListNotebooksContract } from '@/lib/api/contracts/tools/evernote'
import { getValidationErrorMessage, parseRequest } from '@/lib/api/server'
@@ -41,7 +42,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
output: { notebooks },
})
} catch (error) {
const message = error instanceof Error ? error.message : 'Unknown error'
const message = getErrorMessage(error, 'Unknown error')
logger.error('Failed to list notebooks', { error: message })
return NextResponse.json({ success: false, error: message }, { status: 500 })
}
@@ -1,4 +1,5 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { evernoteListTagsContract } from '@/lib/api/contracts/tools/evernote'
import { getValidationErrorMessage, parseRequest } from '@/lib/api/server'
@@ -41,7 +42,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
output: { tags },
})
} catch (error) {
const message = error instanceof Error ? error.message : 'Unknown error'
const message = getErrorMessage(error, 'Unknown error')
logger.error('Failed to list tags', { error: message })
return NextResponse.json({ success: false, error: message }, { status: 500 })
}
@@ -1,4 +1,5 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { evernoteSearchNotesContract } from '@/lib/api/contracts/tools/evernote'
import { getValidationErrorMessage, parseRequest } from '@/lib/api/server'
@@ -52,7 +53,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
},
})
} catch (error) {
const message = error instanceof Error ? error.message : 'Unknown error'
const message = getErrorMessage(error, 'Unknown error')
logger.error('Failed to search notes', { error: message })
return NextResponse.json({ success: false, error: message }, { status: 500 })
}
@@ -1,4 +1,5 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { evernoteUpdateNoteContract } from '@/lib/api/contracts/tools/evernote'
import { getValidationErrorMessage, parseRequest } from '@/lib/api/server'
@@ -61,7 +62,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
output: { note },
})
} catch (error) {
const message = error instanceof Error ? error.message : 'Unknown error'
const message = getErrorMessage(error, 'Unknown error')
logger.error('Failed to update note', { error: message })
return NextResponse.json({ success: false, error: message }, { status: 500 })
}
+2 -1
View File
@@ -1,4 +1,5 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { extendParseContract } from '@/lib/api/contracts/tools/media/document-parse'
import { getValidationErrorMessage, parseRequest } from '@/lib/api/server'
@@ -180,7 +181,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
return NextResponse.json(
{
success: false,
error: error instanceof Error ? error.message : 'Internal server error',
error: getErrorMessage(error, 'Internal server error'),
},
{ status: 500 }
)
+4 -2
View File
@@ -1,4 +1,6 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { generateShortId } from '@sim/utils/id'
import { type NextRequest, NextResponse } from 'next/server'
import { fileManageContract } from '@/lib/api/contracts/tools/file'
import { parseRequest } from '@/lib/api/server'
@@ -314,7 +316,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
}
const lockKey = `file-append:${workspaceId}:${existing.id}`
const lockValue = `${Date.now()}-${Math.random().toString(36).slice(2)}`
const lockValue = `${Date.now()}-${generateShortId()}`
const acquired = await acquireLock(lockKey, lockValue, 30)
if (!acquired) {
return NextResponse.json(
@@ -350,7 +352,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
}
}
} catch (error) {
const message = error instanceof Error ? error.message : 'Unknown error'
const message = getErrorMessage(error, 'Unknown error')
logger.error('File operation failed', { operation: body.operation, error: message })
return NextResponse.json({ success: false, error: message }, { status: 500 })
}
@@ -1,4 +1,5 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { githubLatestCommitContract } from '@/lib/api/contracts/tools/github'
import { parseRequest } from '@/lib/api/server'
@@ -182,7 +183,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
return NextResponse.json(
{
success: false,
error: error instanceof Error ? error.message : 'Unknown error occurred',
error: getErrorMessage(error, 'Unknown error occurred'),
},
{ status: 500 }
)
@@ -1,4 +1,5 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { gmailAddLabelContract } from '@/lib/api/contracts/tools/google'
import { parseRequest } from '@/lib/api/server'
@@ -118,7 +119,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
return NextResponse.json(
{
success: false,
error: error instanceof Error ? error.message : 'Internal server error',
error: getErrorMessage(error, 'Internal server error'),
},
{ status: 500 }
)
@@ -1,4 +1,5 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { gmailArchiveContract } from '@/lib/api/contracts/tools/google'
import { parseRequest } from '@/lib/api/server'
@@ -88,7 +89,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
return NextResponse.json(
{
success: false,
error: error instanceof Error ? error.message : 'Internal server error',
error: getErrorMessage(error, 'Internal server error'),
},
{ status: 500 }
)
+2 -1
View File
@@ -1,4 +1,5 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { gmailDeleteContract } from '@/lib/api/contracts/tools/google'
import { parseRequest } from '@/lib/api/server'
@@ -85,7 +86,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
return NextResponse.json(
{
success: false,
error: error instanceof Error ? error.message : 'Internal server error',
error: getErrorMessage(error, 'Internal server error'),
},
{ status: 500 }
)
+3 -2
View File
@@ -1,4 +1,5 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { gmailDraftContract } from '@/lib/api/contracts/tools/google'
import { parseRequest } from '@/lib/api/server'
@@ -103,7 +104,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
} catch (error) {
logger.error(`[${requestId}] Failed to download attachment ${file.name}:`, error)
throw new Error(
`Failed to download attachment "${file.name}": ${error instanceof Error ? error.message : 'Unknown error'}`
`Failed to download attachment "${file.name}": ${getErrorMessage(error, 'Unknown error')}`
)
}
})
@@ -198,7 +199,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
return NextResponse.json(
{
success: false,
error: error instanceof Error ? error.message : 'Internal server error',
error: getErrorMessage(error, 'Internal server error'),
},
{ status: 500 }
)
@@ -1,4 +1,5 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { gmailEditDraftContract } from '@/lib/api/contracts/tools/google'
import { parseRequest } from '@/lib/api/server'
@@ -99,7 +100,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
} catch (error) {
logger.error(`[${requestId}] Failed to download attachment ${file.name}:`, error)
throw new Error(
`Failed to download attachment "${file.name}": ${error instanceof Error ? error.message : 'Unknown error'}`
`Failed to download attachment "${file.name}": ${getErrorMessage(error, 'Unknown error')}`
)
}
})
@@ -191,7 +192,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
return NextResponse.json(
{
success: false,
error: error instanceof Error ? error.message : 'Internal server error',
error: getErrorMessage(error, 'Internal server error'),
},
{ status: 500 }
)
@@ -1,4 +1,5 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { gmailMarkReadContract } from '@/lib/api/contracts/tools/google'
import { parseRequest } from '@/lib/api/server'
@@ -88,7 +89,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
return NextResponse.json(
{
success: false,
error: error instanceof Error ? error.message : 'Internal server error',
error: getErrorMessage(error, 'Internal server error'),
},
{ status: 500 }
)
@@ -1,4 +1,5 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { gmailMarkUnreadContract } from '@/lib/api/contracts/tools/google'
import { parseRequest } from '@/lib/api/server'
@@ -91,7 +92,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
return NextResponse.json(
{
success: false,
error: error instanceof Error ? error.message : 'Internal server error',
error: getErrorMessage(error, 'Internal server error'),
},
{ status: 500 }
)
+2 -1
View File
@@ -1,4 +1,5 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { gmailMoveContract } from '@/lib/api/contracts/tools/google'
import { parseRequest } from '@/lib/api/server'
@@ -110,7 +111,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
return NextResponse.json(
{
success: false,
error: error instanceof Error ? error.message : 'Internal server error',
error: getErrorMessage(error, 'Internal server error'),
},
{ status: 500 }
)
@@ -1,4 +1,5 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { gmailRemoveLabelContract } from '@/lib/api/contracts/tools/google'
import { parseRequest } from '@/lib/api/server'
@@ -121,7 +122,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
return NextResponse.json(
{
success: false,
error: error instanceof Error ? error.message : 'Internal server error',
error: getErrorMessage(error, 'Internal server error'),
},
{ status: 500 }
)
+3 -2
View File
@@ -1,4 +1,5 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { gmailSendContract } from '@/lib/api/contracts/tools/google'
import { parseRequest } from '@/lib/api/server'
@@ -103,7 +104,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
} catch (error) {
logger.error(`[${requestId}] Failed to download attachment ${file.name}:`, error)
throw new Error(
`Failed to download attachment "${file.name}": ${error instanceof Error ? error.message : 'Unknown error'}`
`Failed to download attachment "${file.name}": ${getErrorMessage(error, 'Unknown error')}`
)
}
})
@@ -193,7 +194,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
return NextResponse.json(
{
success: false,
error: error instanceof Error ? error.message : 'Internal server error',
error: getErrorMessage(error, 'Internal server error'),
},
{ status: 500 }
)
@@ -1,4 +1,5 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { gmailUnarchiveContract } from '@/lib/api/contracts/tools/google'
import { parseRequest } from '@/lib/api/server'
@@ -88,7 +89,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
return NextResponse.json(
{
success: false,
error: error instanceof Error ? error.message : 'Internal server error',
error: getErrorMessage(error, 'Internal server error'),
},
{ status: 500 }
)

Some files were not shown because too many files have changed in this diff Show More