|
1 | 1 | /* Copyright 2024 Marimo. All rights reserved. */ |
2 | 2 |
|
3 | | -import { NotebookPenIcon, SquareArrowOutUpRightIcon } from "lucide-react"; |
| 3 | +import { |
| 4 | + InfoIcon, |
| 5 | + NotebookPenIcon, |
| 6 | + SquareArrowOutUpRightIcon, |
| 7 | +} from "lucide-react"; |
4 | 8 | import { Fragment, type JSX } from "react"; |
5 | 9 | import { |
6 | 10 | Accordion, |
@@ -72,6 +76,8 @@ export const MarimoErrorOutput = ({ |
72 | 76 | titleContents = "Ancestor stopped"; |
73 | 77 | alertVariant = "default"; |
74 | 78 | titleColor = "text-secondary-foreground"; |
| 79 | + } else if (errors.some((e) => e.type === "sql-error")) { |
| 80 | + titleContents = "SQL Error in statement"; |
75 | 81 | } else { |
76 | 82 | // Check for exception type |
77 | 83 | const exceptionError = errors.find((e) => e.type === "exception"); |
@@ -126,6 +132,10 @@ export const MarimoErrorOutput = ({ |
126 | 132 | const unknownErrors = errors.filter( |
127 | 133 | (e): e is Extract<MarimoError, { type: "unknown" }> => e.type === "unknown", |
128 | 134 | ); |
| 135 | + const sqlErrors = errors.filter( |
| 136 | + (e): e is Extract<MarimoError, { type: "sql-error" }> => |
| 137 | + e.type === "sql-error", |
| 138 | + ); |
129 | 139 |
|
130 | 140 | const openScratchpad = () => { |
131 | 141 | chromeActions.openApplication("scratchpad"); |
@@ -485,6 +495,55 @@ export const MarimoErrorOutput = ({ |
485 | 495 | ); |
486 | 496 | } |
487 | 497 |
|
| 498 | + if (sqlErrors.length > 0) { |
| 499 | + messages.push( |
| 500 | + <div key="sql-errors"> |
| 501 | + {sqlErrors.map((error, idx) => { |
| 502 | + const line = |
| 503 | + error.sql_line != null ? (error?.sql_line | 0) + 1 : null; |
| 504 | + const col = error.sql_col != null ? (error?.sql_col | 0) + 1 : null; |
| 505 | + return ( |
| 506 | + <div key={`sql-error-${idx}`} className="space-y-2"> |
| 507 | + <p className="text-muted-foreground">{error.msg}</p> |
| 508 | + {error.hint && ( |
| 509 | + <div className="flex items-start gap-2"> |
| 510 | + <InfoIcon className="h-4 w-4 text-muted-foreground mt-0.5 flex-shrink-0" /> |
| 511 | + <pre className="whitespace-pre-wrap text-sm text-muted-foreground"> |
| 512 | + {error.hint} |
| 513 | + </pre> |
| 514 | + </div> |
| 515 | + )} |
| 516 | + {error.sql_statement && ( |
| 517 | + <div className="bg-muted/50 p-2 rounded text-xs font-mono"> |
| 518 | + <pre className="whitespace-pre-wrap"> |
| 519 | + {error.sql_statement} |
| 520 | + </pre> |
| 521 | + </div> |
| 522 | + )} |
| 523 | + {line !== null && col !== null && ( |
| 524 | + <p className="text-xs text-muted-foreground"> |
| 525 | + Error at line {line}, column {col} |
| 526 | + </p> |
| 527 | + )} |
| 528 | + </div> |
| 529 | + ); |
| 530 | + })} |
| 531 | + {cellId && <AutoFixButton errors={sqlErrors} cellId={cellId} />} |
| 532 | + <Tip title="How to fix SQL errors"> |
| 533 | + <p className="pb-2"> |
| 534 | + SQL parsing errors often occur due to invalid syntax, missing |
| 535 | + keywords, or unsupported SQL features. |
| 536 | + </p> |
| 537 | + <p className="py-2"> |
| 538 | + Check your SQL syntax and ensure you're using supported SQL |
| 539 | + dialect features. The error location can help you identify the |
| 540 | + problematic part of your query. |
| 541 | + </p> |
| 542 | + </Tip> |
| 543 | + </div>, |
| 544 | + ); |
| 545 | + } |
| 546 | + |
488 | 547 | return messages; |
489 | 548 | }; |
490 | 549 |
|
|
0 commit comments