Skip to content

Commit 11ec037

Browse files
committed
feat(vscode): diagnostic for bad config.yaml error
- return error - filter diagnostics so it doesn't show in wrong place
1 parent 466968e commit 11ec037

File tree

5 files changed

+76
-5
lines changed

5 files changed

+76
-5
lines changed

pnpm-lock.yaml

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sqlmesh/core/config/loader.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ def load_config_from_paths(
9191
"SQLMesh project config could not be found. Point the cli to the project path with `sqlmesh -p`. If you haven't set up the SQLMesh project, run `sqlmesh init`."
9292
)
9393

94+
yaml_config_path: t.Optional[Path] = None
9495
for path in [*project_paths, *personal_paths]:
9596
if not path.exists():
9697
continue
@@ -107,8 +108,9 @@ def load_config_from_paths(
107108
if extension in ("yml", "yaml"):
108109
if config_name != "config" and not python_config:
109110
raise ConfigError(
110-
"YAML configs do not support multiple configs. Use Python instead."
111+
"YAML configs do not support multiple configs. Use Python instead.",
111112
)
113+
yaml_config_path = path.resolve()
112114
non_python_configs.append(load_config_from_yaml(path))
113115
elif extension == "py":
114116
try:
@@ -149,7 +151,8 @@ def load_config_from_paths(
149151
except ValidationError as e:
150152
raise ConfigError(
151153
validation_error_message(e, "Invalid project config:")
152-
+ "\n\nVerify your config.yaml and environment variables."
154+
+ "\n\nVerify your config.yaml and environment variables.",
155+
location=yaml_config_path,
153156
)
154157

155158
no_dialect_err_msg = "Default model SQL dialect is a required configuration parameter. Set it in the `model_defaults` `dialect` key in your config file."

sqlmesh/lsp/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -779,7 +779,7 @@ def _get_diagnostics_for_uri(self, uri: URI) -> t.Tuple[t.List[types.Diagnostic]
779779
return LSPContext.diagnostics_to_lsp_diagnostics(diagnostics), 0
780780
except ConfigError as config_error:
781781
diagnostic, error = context_error_to_diagnostic(config_error, uri_filter=uri)
782-
if diagnostic:
782+
if diagnostic and diagnostic[0] == uri.value:
783783
return [diagnostic[1]], 0
784784
return [], 0
785785

vscode/extension/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@
155155
"ts-loader": "^9.5.2",
156156
"typescript": "^5.8.3",
157157
"typescript-eslint": "^8.35.1",
158-
"vitest": "^3.2.4"
158+
"vitest": "^3.2.4",
159+
"yaml": "^2.8.0"
159160
}
160161
}

vscode/extension/tests/broken_project.spec.ts

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,15 @@ import { test, expect } from './fixtures'
22
import fs from 'fs-extra'
33
import os from 'os'
44
import path from 'path'
5-
import { openLineageView, saveFile, SUSHI_SOURCE_PATH } from './utils'
5+
import {
6+
openLineageView,
7+
runCommand,
8+
saveFile,
9+
SUSHI_SOURCE_PATH,
10+
} from './utils'
611
import { createPythonInterpreterSettingsSpecifier } from './utils_code_server'
12+
import { execAsync } from '../src/utilities/exec'
13+
import yaml from 'yaml'
714

815
test('bad project, double model', async ({ page, sharedCodeServer }) => {
916
const tempDir = await fs.mkdtemp(
@@ -253,3 +260,60 @@ test('bad project, double model, check lineage', async ({
253260

254261
await page.waitForTimeout(500)
255262
})
263+
264+
const setup = async (tempDir: string) => {
265+
// Run the sqlmesh CLI from the root of the repo using the local path
266+
const sqlmeshCliPath = path.resolve(__dirname, '../../../.venv/bin/sqlmesh')
267+
const result = await execAsync(sqlmeshCliPath, ['init', 'duckdb'], {
268+
cwd: tempDir,
269+
})
270+
expect(result.exitCode).toBe(0)
271+
}
272+
273+
test.describe('Bad config.py/config.yaml file issues', () => {
274+
test('sqlmesh init, then corrupted config.yaml, bad parameters', async ({
275+
page,
276+
sharedCodeServer,
277+
}) => {
278+
const tempDir = await fs.mkdtemp(
279+
path.join(os.tmpdir(), 'vscode-test-tcloud-'),
280+
)
281+
await setup(tempDir)
282+
await createPythonInterpreterSettingsSpecifier(tempDir)
283+
284+
const configYamlPath = path.join(tempDir, 'config.yaml')
285+
// Write an invalid YAML to config.yaml
286+
const config = {
287+
gateway: 'test',
288+
}
289+
// Write config to the yaml file
290+
await fs.writeFile(configYamlPath, yaml.stringify(config))
291+
292+
await page.goto(
293+
`http://127.0.0.1:${sharedCodeServer.codeServerPort}/?folder=${tempDir}`,
294+
)
295+
await page.waitForLoadState('networkidle')
296+
297+
// Open full_model.sql model
298+
await page
299+
.getByRole('treeitem', { name: 'models', exact: true })
300+
.locator('a')
301+
.click()
302+
await page
303+
.getByRole('treeitem', { name: 'full_model.sql', exact: true })
304+
.locator('a')
305+
.click()
306+
307+
// Wait for the error to appear
308+
await page.waitForSelector('text=Error creating context')
309+
310+
// Open the problems view
311+
await runCommand(page, 'View: Focus Problems')
312+
313+
// Asser that the error is present in the problems view
314+
await page
315+
.getByText('Invalid project config:', { exact: true })
316+
.isVisible({ timeout: 1_000 })
317+
await page.getByText('Invalid project config:', { exact: true }).click()
318+
})
319+
})

0 commit comments

Comments
 (0)