From 51280d4e77c685cda81f84f36097d07f9f557124 Mon Sep 17 00:00:00 2001 From: Andrew Pareles Date: Fri, 22 Nov 2024 00:43:07 -0800 Subject: [PATCH] error ui improvements --- package-lock.json | 87 +++++++++++- package.json | 2 + .../contrib/void/browser/react/build.js | 1 + .../browser/react/src/util/ErrorDisplay.tsx | 128 ++++++++++++++++++ 4 files changed, 216 insertions(+), 2 deletions(-) create mode 100644 src/vs/workbench/contrib/void/browser/react/src/util/ErrorDisplay.tsx diff --git a/package-lock.json b/package-lock.json index 70f4138a..87c05495 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,6 +23,7 @@ "@vscode/sudo-prompt": "9.3.1", "@vscode/tree-sitter-wasm": "^0.0.4", "@vscode/vscode-languagedetection": "1.0.21", + "@vscode/webview-ui-toolkit": "^1.4.0", "@vscode/windows-mutex": "^0.5.0", "@vscode/windows-process-tree": "^0.6.0", "@vscode/windows-registry": "^1.1.0", @@ -38,6 +39,7 @@ "https-proxy-agent": "^7.0.2", "jschardet": "3.1.3", "kerberos": "2.1.1", + "lucide-react": "^0.460.0", "minimist": "^1.2.6", "native-is-elevated": "0.7.0", "native-keymap": "^3.3.5", @@ -2065,6 +2067,52 @@ "resolved": "https://registry.npmjs.org/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.9.tgz", "integrity": "sha512-n1VPsljTSkthsAFYdiWfC+DKzK2WwcRp83Y1YAqdX552BstvsDjft9YXppjUzp11BPsapDoO1LDgrDB0XVsfNQ==" }, + "node_modules/@microsoft/fast-element": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/@microsoft/fast-element/-/fast-element-1.14.0.tgz", + "integrity": "sha512-zXvuSOzvsu8zDTy9eby8ix8VqLop2rwKRgp++ZN2kTCsoB3+QJVoaGD2T/Cyso2ViZQFXNpiNCVKfnmxBvmWkQ==", + "license": "MIT" + }, + "node_modules/@microsoft/fast-foundation": { + "version": "2.50.0", + "resolved": "https://registry.npmjs.org/@microsoft/fast-foundation/-/fast-foundation-2.50.0.tgz", + "integrity": "sha512-8mFYG88Xea1jZf2TI9Lm/jzZ6RWR8x29r24mGuLojNYqIR2Bl8+hnswoV6laApKdCbGMPKnsAL/O68Q0sRxeVg==", + "license": "MIT", + "dependencies": { + "@microsoft/fast-element": "^1.14.0", + "@microsoft/fast-web-utilities": "^5.4.1", + "tabbable": "^5.2.0", + "tslib": "^1.13.0" + } + }, + "node_modules/@microsoft/fast-foundation/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "license": "0BSD" + }, + "node_modules/@microsoft/fast-react-wrapper": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@microsoft/fast-react-wrapper/-/fast-react-wrapper-0.3.25.tgz", + "integrity": "sha512-jKzmk2xJV93RL/jEFXEZgBvXlKIY4N4kXy3qrjmBfFpqNi3VjY+oUTWyMnHRMC5EUhIFxD+Y1VD4u9uIPX3jQw==", + "license": "MIT", + "dependencies": { + "@microsoft/fast-element": "^1.14.0", + "@microsoft/fast-foundation": "^2.50.0" + }, + "peerDependencies": { + "react": ">=16.9.0" + } + }, + "node_modules/@microsoft/fast-web-utilities": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/@microsoft/fast-web-utilities/-/fast-web-utilities-5.4.1.tgz", + "integrity": "sha512-ReWYncndjV3c8D8iq9tp7NcFNc1vbVHvcBFPME2nNFKNbS1XCesYZGlIlf3ot5EmuOXPlrzUHOWzQ2vFpIkqDg==", + "license": "MIT", + "dependencies": { + "exenv-es6": "^1.1.1" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -4111,6 +4159,21 @@ "node": ">= 0.6" } }, + "node_modules/@vscode/webview-ui-toolkit": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@vscode/webview-ui-toolkit/-/webview-ui-toolkit-1.4.0.tgz", + "integrity": "sha512-modXVHQkZLsxgmd5yoP3ptRC/G8NBDD+ob+ngPiWNQdlrH6H1xR/qgOBD85bfU3BhOB5sZzFWBwwhp9/SfoHww==", + "license": "MIT", + "dependencies": { + "@microsoft/fast-element": "^1.12.0", + "@microsoft/fast-foundation": "^2.49.4", + "@microsoft/fast-react-wrapper": "^0.3.22", + "tslib": "^2.6.2" + }, + "peerDependencies": { + "react": ">=16.9.0" + } + }, "node_modules/@vscode/windows-ca-certs": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/@vscode/windows-ca-certs/-/windows-ca-certs-0.3.1.tgz", @@ -8022,6 +8085,12 @@ "node": ">=0.8.x" } }, + "node_modules/exenv-es6": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/exenv-es6/-/exenv-es6-1.1.1.tgz", + "integrity": "sha512-vlVu3N8d6yEMpMsEm+7sUBAI81aqYYuEvfK0jNqmdb/OPXzzH7QWDDnVjMvDSY47JdHEqx/dfC/q8WkfoTmpGQ==", + "license": "MIT" + }, "node_modules/expand-brackets": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", @@ -14202,6 +14271,15 @@ "es5-ext": "~0.10.2" } }, + "node_modules/lucide-react": { + "version": "0.460.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.460.0.tgz", + "integrity": "sha512-BVtq/DykVeIvRTJvRAgCsOwaGL8Un3Bxh8MbDxMhEWlZay3T4IpEKDEpwt5KZ0KJMHzgm6jrltxlT5eXOWXDHg==", + "license": "ISC", + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0-rc" + } + }, "node_modules/make-dir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", @@ -20392,6 +20470,12 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "node_modules/tabbable": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-5.3.3.tgz", + "integrity": "sha512-QD9qKY3StfbZqWOPLp0++pOrAVb/HbUi5xCc8cUo4XjP19808oaMiDzn0leBY5mCespIBM0CIZePzZjgzR83kA==", + "license": "MIT" + }, "node_modules/table": { "version": "5.4.6", "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", @@ -21271,8 +21355,7 @@ "node_modules/tslib": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", - "dev": true + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/tsscmp": { "version": "1.0.6", diff --git a/package.json b/package.json index 0a5189a7..dc1b4e96 100644 --- a/package.json +++ b/package.json @@ -85,6 +85,7 @@ "@vscode/sudo-prompt": "9.3.1", "@vscode/tree-sitter-wasm": "^0.0.4", "@vscode/vscode-languagedetection": "1.0.21", + "@vscode/webview-ui-toolkit": "^1.4.0", "@vscode/windows-mutex": "^0.5.0", "@vscode/windows-process-tree": "^0.6.0", "@vscode/windows-registry": "^1.1.0", @@ -100,6 +101,7 @@ "https-proxy-agent": "^7.0.2", "jschardet": "3.1.3", "kerberos": "2.1.1", + "lucide-react": "^0.460.0", "minimist": "^1.2.6", "native-is-elevated": "0.7.0", "native-keymap": "^3.3.5", diff --git a/src/vs/workbench/contrib/void/browser/react/build.js b/src/vs/workbench/contrib/void/browser/react/build.js index 80befcdb..5383c4a4 100755 --- a/src/vs/workbench/contrib/void/browser/react/build.js +++ b/src/vs/workbench/contrib/void/browser/react/build.js @@ -10,3 +10,4 @@ execSync('npx scope-tailwind ./src -o src2/ -s void-scope -c styles.css -p "pref execSync('npx tsup') +console.log('✅ Done building! Press Cmd+Shift+B again.') diff --git a/src/vs/workbench/contrib/void/browser/react/src/util/ErrorDisplay.tsx b/src/vs/workbench/contrib/void/browser/react/src/util/ErrorDisplay.tsx new file mode 100644 index 00000000..bd5240bb --- /dev/null +++ b/src/vs/workbench/contrib/void/browser/react/src/util/ErrorDisplay.tsx @@ -0,0 +1,128 @@ +import React, { useState } from 'react'; +import { AlertCircle, ChevronDown, ChevronUp, X } from 'lucide-react'; +import { } from '@vscode/webview-ui-toolkit/react'; + + +// Get detailed error information +const getErrorDetails = (error: any) => { + + let details: { message: string, name: string, stack: string | null, cause: string | null, code: string | null, additional: Record }; + + const e = error instanceof Error ? error : new Error(String(error)); + + details = { + message: e.message || String(e), + name: e.name || 'Error', + stack: e.stack || null, + cause: e.cause ? String(e.cause) : null, + code: (e as any).code || null, + additional: {} + } + + + // Collect any additional properties from the e + for (let prop of Object.getOwnPropertyNames(e).filter((prop) => !Object.keys(details).includes(prop))) + details.additional[prop] = (e as any)[prop] + + return details; +}; + + + +const ErrorDisplay = ({ + error, + onDismiss = null, + showDismiss = true, + className = '' +}: { + error: Error, + onDismiss: (() => void) | null, + showDismiss?: boolean, + className?: string +}) => { + const [isExpanded, setIsExpanded] = useState(false); + + const details = getErrorDetails(error); + const hasDetails = details.stack || details.cause || Object.keys(details.additional).length > 0; + + return ( +
+ {/* Header */} +
+
+ +
+

+ {details.name} +

+

+ {details.message} +

+
+
+ +
+ {hasDetails && ( + + )} + {showDismiss && onDismiss && ( + + )} +
+
+ + {/* Expandable Details */} + {isExpanded && hasDetails && ( +
+ {details.code && ( +
+ Error Code: + {details.code} +
+ )} + + {details.cause && ( +
+ Cause: + {details.cause} +
+ )} + + {Object.keys(details.additional).length > 0 && ( +
+ Additional Information: +
+								{JSON.stringify(details.additional, null, 2)}
+							
+
+ )} + + {details.stack && ( +
+ Stack Trace: +
+								{details.stack}
+							
+
+ )} +
+ )} +
+ ); +}; + +export default ErrorDisplay;