fix(files): replace instanceof Error checks with toError() and fix skeleton tokens

- Use toError() from @sim/utils/errors across all catch blocks in
  file-viewer.tsx, preview-panel.tsx, and route.ts instead of the
  prohibited `err instanceof Error ? err.message : fallback` pattern
- Fix loading skeleton in files.tsx: bg-white → bg-[var(--surface-2)]
  and shadow-[var(--shadow-medium)] → shadow-medium
This commit is contained in:
waleed
2026-04-27 19:57:28 -07:00
parent 3250264de6
commit 4d3da794d8
4 changed files with 14 additions and 11 deletions

View File

@@ -1,5 +1,6 @@
import { AuditAction, AuditResourceType, recordAudit } from '@sim/audit'
import { createLogger } from '@sim/logger'
import { toError } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { getSession } from '@/lib/auth'
import { withRouteHandler } from '@/lib/core/utils/with-route-handler'
@@ -80,7 +81,7 @@ export const PUT = withRouteHandler(
file: updatedFile,
})
} catch (error) {
const errorMessage = error instanceof Error ? error.message : 'Failed to update file content'
const errorMessage = toError(error).message || 'Failed to update file content'
const isNotFound = errorMessage.includes('File not found')
const isQuotaExceeded = errorMessage.includes('Storage limit exceeded')
const status = isNotFound ? 404 : isQuotaExceeded ? 402 : 500

View File

@@ -3,6 +3,7 @@
import { memo, useCallback, useEffect, useMemo, useReducer, useRef, useState } from 'react'
import type { OnMount } from '@monaco-editor/react'
import { createLogger } from '@sim/logger'
import { toError } from '@sim/utils/errors'
import { ZoomIn, ZoomOut } from 'lucide-react'
import dynamic from 'next/dynamic'
import { Button, Skeleton } from '@/components/emcn'
@@ -1024,7 +1025,7 @@ const IframePreview = memo(function IframePreview({
setStreamingBuffer(buf)
} catch (err) {
if (!cancelled && !(err instanceof DOMException && err.name === 'AbortError')) {
const msg = err instanceof Error ? err.message : 'Failed to render PDF'
const msg = toError(err).message || 'Failed to render PDF'
if (streamingBufferRef.current || shouldSuppressStreamingDocumentError(msg)) {
logger.info('Suppressing transient PDF streaming preview error', { error: msg })
} else {
@@ -1473,7 +1474,7 @@ const DocxPreview = memo(function DocxPreview({
}
} catch (err) {
if (!cancelled) {
const msg = err instanceof Error ? err.message : 'Failed to render document'
const msg = toError(err).message || 'Failed to render document'
logger.error('DOCX render failed', { error: msg })
setRenderError(msg)
}
@@ -1545,7 +1546,7 @@ const DocxPreview = memo(function DocxPreview({
containerRef.current.innerHTML = previousHtml
setHasRenderedPreview(true)
}
const msg = err instanceof Error ? err.message : 'Failed to render document'
const msg = toError(err).message || 'Failed to render document'
if (previousHtml || shouldSuppressStreamingDocumentError(msg)) {
logger.info('Suppressing transient DOCX streaming preview error', { error: msg })
} else {
@@ -1749,7 +1750,7 @@ function PptxPreview({
)
} catch (err) {
if (!cancelled && !(err instanceof DOMException && err.name === 'AbortError')) {
const msg = err instanceof Error ? err.message : 'Failed to render presentation'
const msg = toError(err).message || 'Failed to render presentation'
if (shouldSuppressStreamingPptxError(msg)) {
logger.info('Suppressing transient PPTX streaming preview error', { error: msg })
} else {
@@ -1801,7 +1802,7 @@ function PptxPreview({
}
} catch (err) {
if (!cancelled) {
const msg = err instanceof Error ? err.message : 'Failed to render presentation'
const msg = toError(err).message || 'Failed to render presentation'
logger.error('PPTX render failed', { error: msg })
setRenderError(msg)
}
@@ -1911,7 +1912,7 @@ const XlsxPreview = memo(function XlsxPreview({
}
} catch (err) {
if (!cancelled) {
const msg = err instanceof Error ? err.message : 'Failed to parse spreadsheet'
const msg = toError(err).message || 'Failed to parse spreadsheet'
logger.error('XLSX parse failed', { error: msg })
setRenderError(msg)
}
@@ -1949,7 +1950,7 @@ const XlsxPreview = memo(function XlsxPreview({
}
} catch (err) {
if (!cancelled) {
const msg = err instanceof Error ? err.message : 'Failed to parse sheet'
const msg = toError(err).message || 'Failed to parse sheet'
logger.error('XLSX sheet parse failed', { error: msg })
setRenderError(msg)
}
@@ -2042,7 +2043,7 @@ const XlsxPreview = memo(function XlsxPreview({
setIsDirty(false)
onSaveStatusChangeRef.current?.('saved')
} catch (err) {
logger.error('XLSX save failed', { error: err instanceof Error ? err.message : String(err) })
logger.error('XLSX save failed', { error: toError(err).message })
onSaveStatusChangeRef.current?.('error')
} finally {
isSavingRef.current = false

View File

@@ -8,6 +8,7 @@ import remarkBreaks from 'remark-breaks'
import remarkGfm from 'remark-gfm'
import { Streamdown } from 'streamdown'
import 'streamdown/styles.css'
import { toError } from '@sim/utils/errors'
import { generateShortId } from '@sim/utils/id'
import { Checkbox, CopyCodeButton, highlight, languages } from '@/components/emcn'
import '@/components/emcn/components/code/code.css'
@@ -270,7 +271,7 @@ const MermaidDiagram = memo(function MermaidDiagram({ definition }: { definition
}
} catch (err) {
if (!cancelled) {
setError(err instanceof Error ? err.message : 'Failed to render diagram')
setError(toError(err).message || 'Failed to render diagram')
setSvg(null)
}
}

View File

@@ -1041,7 +1041,7 @@ export function Files() {
{[0, 1].map((i) => (
<div
key={i}
className='w-full max-w-[640px] shrink-0 rounded-md bg-white p-8 shadow-[var(--shadow-medium)]'
className='w-full max-w-[640px] shrink-0 rounded-md bg-[var(--surface-2)] p-8 shadow-medium'
style={{ aspectRatio: '1 / 1.414' }}
>
<div className='flex flex-col gap-3'>