mirror of
https://github.com/block/goose.git
synced 2026-07-17 12:56:20 +02:00
Improve error message logging from electron (#7130)
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import { Button } from './ui/button';
|
||||
import { AlertTriangle } from 'lucide-react';
|
||||
import { errorMessage } from '../utils/conversionUtils';
|
||||
import { errorMessage, formatErrorForLogging } from '../utils/conversionUtils';
|
||||
import { trackErrorWithContext, trackEvent, getErrorType } from '../utils/analytics';
|
||||
|
||||
function getCurrentPage(): string {
|
||||
@@ -10,7 +10,8 @@ function getCurrentPage(): string {
|
||||
|
||||
// Capture unhandled promise rejections
|
||||
window.addEventListener('unhandledrejection', (event) => {
|
||||
window.electron.logInfo(`[UNHANDLED REJECTION] ${event.reason}`);
|
||||
const reasonStr = formatErrorForLogging(event.reason);
|
||||
window.electron.logInfo(`[UNHANDLED REJECTION] ${reasonStr}`);
|
||||
trackErrorWithContext(event.reason, {
|
||||
component: 'global',
|
||||
page: getCurrentPage(),
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from '../../ui/dialog';
|
||||
import { errorMessage } from '../../../utils/conversionUtils';
|
||||
|
||||
const HelpText = () => (
|
||||
<div className="text-sm flex-col space-y-4 text-text-muted">
|
||||
@@ -39,7 +40,7 @@ const HelpText = () => (
|
||||
|
||||
const ErrorDisplay = ({ error }: { error: Error }) => (
|
||||
<div className="text-sm text-text-muted">
|
||||
<div className="text-red-600">Error reading .goosehints file: {JSON.stringify(error)}</div>
|
||||
<div className="text-red-600">Error reading .goosehints file: {errorMessage(error)}</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
|
||||
@@ -19,20 +19,7 @@ import { useModelAndProvider } from '../../../ModelAndProviderContext';
|
||||
import { AlertTriangle, LogIn } from 'lucide-react';
|
||||
import { ProviderDetails, removeCustomProvider, configureProviderOauth } from '../../../../api';
|
||||
import { Button } from '../../../../components/ui/button';
|
||||
|
||||
const formatErrorMessage = (error: unknown): string => {
|
||||
if (error instanceof Error) {
|
||||
return error.message;
|
||||
}
|
||||
if (typeof error === 'string') {
|
||||
return error;
|
||||
}
|
||||
try {
|
||||
return JSON.stringify(error);
|
||||
} catch {
|
||||
return String(error);
|
||||
}
|
||||
};
|
||||
import { errorMessage } from '../../../../utils/conversionUtils';
|
||||
|
||||
interface ProviderConfigurationModalProps {
|
||||
provider: ProviderDetails;
|
||||
@@ -87,7 +74,7 @@ export default function ProviderConfigurationModal({
|
||||
onClose();
|
||||
}
|
||||
} catch (err) {
|
||||
setError(`OAuth login failed: ${formatErrorMessage(err)}`);
|
||||
setError(`OAuth login failed: ${errorMessage(err)}`);
|
||||
} finally {
|
||||
setIsOAuthLoading(false);
|
||||
}
|
||||
@@ -130,7 +117,7 @@ export default function ProviderConfigurationModal({
|
||||
onClose();
|
||||
}
|
||||
} catch (error) {
|
||||
setError(formatErrorMessage(error));
|
||||
setError(errorMessage(error));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ import { expandTilde } from './utils/pathUtils';
|
||||
import log from './utils/logger';
|
||||
import { ensureWinShims } from './utils/winShims';
|
||||
import { addRecentDir, loadRecentDirs } from './utils/recentDirs';
|
||||
import { formatAppName, errorMessage } from './utils/conversionUtils';
|
||||
import { formatAppName, errorMessage, formatErrorForLogging } from './utils/conversionUtils';
|
||||
import type { Settings } from './utils/settings';
|
||||
import { defaultKeyboardShortcuts, getKeyboardShortcuts } from './utils/settings';
|
||||
import * as crypto from 'crypto';
|
||||
@@ -1116,12 +1116,12 @@ const handleFatalError = (error: Error) => {
|
||||
};
|
||||
|
||||
process.on('uncaughtException', (error) => {
|
||||
console.error('Uncaught Exception:', error);
|
||||
console.error('Uncaught Exception:', formatErrorForLogging(error));
|
||||
handleFatalError(error);
|
||||
});
|
||||
|
||||
process.on('unhandledRejection', (error) => {
|
||||
console.error('Unhandled Rejection:', error);
|
||||
console.error('Unhandled Rejection:', formatErrorForLogging(error));
|
||||
handleFatalError(error instanceof Error ? error : new Error(String(error)));
|
||||
});
|
||||
|
||||
|
||||
@@ -241,10 +241,10 @@ export function trackPageView(page: string, referrer?: string): void {
|
||||
export function trackError(
|
||||
errorType: string,
|
||||
options: {
|
||||
component?: string; // React component name
|
||||
page?: string; // Current route/page
|
||||
action?: string; // What user was doing
|
||||
stackSummary?: string; // Use getStackSummary() to generate
|
||||
component?: string;
|
||||
page?: string;
|
||||
action?: string;
|
||||
stackSummary?: string;
|
||||
recoverable?: boolean;
|
||||
} = {}
|
||||
): void {
|
||||
|
||||
@@ -22,6 +22,20 @@ export function errorMessage(err: Error | unknown, default_value?: string) {
|
||||
}
|
||||
}
|
||||
|
||||
export function formatErrorForLogging(error: unknown): string {
|
||||
if (error instanceof Error) {
|
||||
return `${error.name}: ${error.message}${error.stack ? `\n${error.stack}` : ''}`;
|
||||
}
|
||||
if (typeof error === 'object' && error !== null) {
|
||||
try {
|
||||
return JSON.stringify(error, null, 2);
|
||||
} catch {
|
||||
return String(error);
|
||||
}
|
||||
}
|
||||
return String(error);
|
||||
}
|
||||
|
||||
export async function compressImageDataUrl(dataUrl: string): Promise<string> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const img = new globalThis.Image();
|
||||
|
||||
Reference in New Issue
Block a user