From 4d3da794d8a63bec9b68501ee5ed6e3d79e84e85 Mon Sep 17 00:00:00 2001 From: waleed Date: Mon, 27 Apr 2026 19:57:28 -0700 Subject: [PATCH] fix(files): replace instanceof Error checks with toError() and fix skeleton tokens MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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 --- .../[id]/files/[fileId]/content/route.ts | 3 ++- .../components/file-viewer/file-viewer.tsx | 17 +++++++++-------- .../components/file-viewer/preview-panel.tsx | 3 ++- .../app/workspace/[workspaceId]/files/files.tsx | 2 +- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/apps/sim/app/api/workspaces/[id]/files/[fileId]/content/route.ts b/apps/sim/app/api/workspaces/[id]/files/[fileId]/content/route.ts index 6dc7255b5a..155f426607 100644 --- a/apps/sim/app/api/workspaces/[id]/files/[fileId]/content/route.ts +++ b/apps/sim/app/api/workspaces/[id]/files/[fileId]/content/route.ts @@ -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 diff --git a/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/file-viewer.tsx b/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/file-viewer.tsx index 1f4cc1085b..52df457f7c 100644 --- a/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/file-viewer.tsx +++ b/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/file-viewer.tsx @@ -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 diff --git a/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/preview-panel.tsx b/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/preview-panel.tsx index 24b90bf0cb..2795573ae7 100644 --- a/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/preview-panel.tsx +++ b/apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/preview-panel.tsx @@ -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) } } diff --git a/apps/sim/app/workspace/[workspaceId]/files/files.tsx b/apps/sim/app/workspace/[workspaceId]/files/files.tsx index 1c063f1ee9..e47c017117 100644 --- a/apps/sim/app/workspace/[workspaceId]/files/files.tsx +++ b/apps/sim/app/workspace/[workspaceId]/files/files.tsx @@ -1041,7 +1041,7 @@ export function Files() { {[0, 1].map((i) => (