feat(docs): add auto-generated troubleshooting section to database pages (#37345)

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Evan Rusackas
2026-01-22 14:43:02 -08:00
committed by GitHub
parent 760227d630
commit b7a5b24a54
6 changed files with 1473 additions and 10 deletions

View File

@@ -26,6 +26,7 @@ import {
KeyOutlined,
SearchOutlined,
LinkOutlined,
BugOutlined,
} from '@ant-design/icons';
import type { DatabaseData, DatabaseInfo, TimeGrains } from './types';
@@ -44,6 +45,8 @@ interface TableEntry {
hasDrivers: boolean;
hasAuthMethods: boolean;
hasConnectionString: boolean;
hasCustomErrors: boolean;
customErrorCount: number;
joins?: boolean;
subqueries?: boolean;
supports_dynamic_schema?: boolean;
@@ -223,6 +226,8 @@ const DatabaseIndex: React.FC<DatabaseIndexProps> = ({ data }) => {
db.documentation?.connection_string ||
(db.documentation?.drivers?.length ?? 0) > 0
),
hasCustomErrors: (db.documentation?.custom_errors?.length ?? 0) > 0,
customErrorCount: db.documentation?.custom_errors?.length ?? 0,
isCompatible: false,
});
@@ -246,6 +251,8 @@ const DatabaseIndex: React.FC<DatabaseIndexProps> = ({ data }) => {
hasDrivers: false,
hasAuthMethods: false,
hasConnectionString: Boolean(compat.connection_string),
hasCustomErrors: false,
customErrorCount: 0,
joins: db.joins,
subqueries: db.subqueries,
supports_dynamic_schema: db.supports_dynamic_schema,
@@ -457,7 +464,7 @@ const DatabaseIndex: React.FC<DatabaseIndexProps> = ({ data }) => {
{
title: 'Documentation',
key: 'docs',
width: 150,
width: 180,
render: (_: unknown, record: TableEntry) => (
<div style={{ display: 'flex', gap: '4px', flexWrap: 'wrap' }}>
{record.hasConnectionString && (
@@ -475,6 +482,13 @@ const DatabaseIndex: React.FC<DatabaseIndexProps> = ({ data }) => {
Auth
</Tag>
)}
{record.hasCustomErrors && (
<Tooltip title={`${record.customErrorCount} troubleshooting tips`}>
<Tag icon={<BugOutlined />} color="volcano">
Errors
</Tag>
</Tooltip>
)}
</div>
),
},

View File

@@ -39,6 +39,7 @@ import {
BookOutlined,
EditOutlined,
GithubOutlined,
BugOutlined,
} from '@ant-design/icons';
import type { DatabaseInfo } from './types';
@@ -414,6 +415,132 @@ const DatabasePage: React.FC<DatabasePageProps> = ({ database, name }) => {
);
};
// Render troubleshooting / custom errors section
const renderTroubleshooting = () => {
if (!docs?.custom_errors?.length) return null;
// Group errors by category
const errorsByCategory: Record<string, typeof docs.custom_errors> = {};
for (const error of docs.custom_errors) {
const category = error.category || 'General';
if (!errorsByCategory[category]) {
errorsByCategory[category] = [];
}
errorsByCategory[category].push(error);
}
// Define category order for consistent display
const categoryOrder = [
'Authentication',
'Connection',
'Permissions',
'Query',
'Configuration',
'General',
];
const sortedCategories = Object.keys(errorsByCategory).sort((a, b) => {
const aIdx = categoryOrder.indexOf(a);
const bIdx = categoryOrder.indexOf(b);
if (aIdx === -1 && bIdx === -1) return a.localeCompare(b);
if (aIdx === -1) return 1;
if (bIdx === -1) return -1;
return aIdx - bIdx;
});
// Category colors
const categoryColors: Record<string, string> = {
Authentication: 'orange',
Connection: 'red',
Permissions: 'purple',
Query: 'blue',
Configuration: 'cyan',
General: 'default',
};
return (
<Card
title={
<>
<BugOutlined /> Troubleshooting
</>
}
style={{ marginBottom: 16 }}
>
<Paragraph type="secondary">
Common error messages you may encounter when connecting to or querying{' '}
{name}, along with their causes and solutions.
</Paragraph>
<Collapse accordion>
{sortedCategories.map((category) => (
<Panel
header={
<span>
<Tag color={categoryColors[category] || 'default'}>
{category}
</Tag>
{errorsByCategory[category].length} error
{errorsByCategory[category].length !== 1 ? 's' : ''}
</span>
}
key={category}
>
{errorsByCategory[category].map((error, idx) => (
<div
key={idx}
style={{
marginBottom:
idx < errorsByCategory[category].length - 1 ? 16 : 0,
paddingBottom:
idx < errorsByCategory[category].length - 1 ? 16 : 0,
borderBottom:
idx < errorsByCategory[category].length - 1
? '1px solid var(--ifm-color-emphasis-200)'
: 'none',
}}
>
<div style={{ marginBottom: 8 }}>
<Text strong>{error.description || error.error_type}</Text>
</div>
<Alert
message={error.message_template}
type="error"
style={{ marginBottom: 8 }}
/>
{error.invalid_fields && error.invalid_fields.length > 0 && (
<div style={{ marginBottom: 8 }}>
<Text type="secondary">Check these fields: </Text>
{error.invalid_fields.map((field) => (
<Tag key={field} color="warning">
{field}
</Tag>
))}
</div>
)}
{error.issue_codes && error.issue_codes.length > 0 && (
<div>
<Text type="secondary">Related issue codes: </Text>
{error.issue_codes.map((code) => (
<Tag key={code}>
<a
href={`/docs/using-superset/issue-codes#issue-${code}`}
style={{ color: 'inherit' }}
>
Issue {code}
</a>
</Tag>
))}
</div>
)}
</div>
))}
</Panel>
))}
</Collapse>
</Card>
);
};
return (
<div
className="database-page"
@@ -556,6 +683,9 @@ const DatabasePage: React.FC<DatabasePageProps> = ({ database, name }) => {
{/* Time Grains */}
{renderTimeGrains()}
{/* Troubleshooting / Custom Errors */}
{renderTroubleshooting()}
{/* Compatible Databases */}
{renderCompatibleDatabases()}

View File

@@ -86,6 +86,17 @@ export interface CompatibleDatabase {
docs_url?: string;
}
export interface CustomError {
error_type: string; // e.g., "CONNECTION_INVALID_USERNAME_ERROR"
message_template: string; // e.g., 'The username "%(username)s" does not exist.'
regex_pattern?: string; // The regex pattern that matches this error (optional, for reference)
regex_name?: string; // The name of the regex constant (e.g., "CONNECTION_INVALID_USERNAME_REGEX")
invalid_fields?: string[]; // Fields that are invalid, e.g., ["username", "password"]
issue_codes?: number[]; // Related issue codes from ISSUE_CODES mapping
category?: string; // Error category: "Authentication", "Connection", "Query", etc.
description?: string; // Human-readable short description of the error type
}
export interface DatabaseDocumentation {
description?: string;
logo?: string;
@@ -111,6 +122,7 @@ export interface DatabaseDocumentation {
sqlalchemy_docs_url?: string;
advanced_features?: Record<string, string>;
compatible_databases?: CompatibleDatabase[];
custom_errors?: CustomError[]; // Database-specific error messages and troubleshooting info
}
export interface TimeGrains {

File diff suppressed because it is too large Load Diff