Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 12 additions & 7 deletions vscode/extension/src/lsp/custom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ interface RenderModelRequest {
textDocumentUri: string
}

interface RenderModelResponse {
interface RenderModelResponse extends BaseResponse {
models: RenderModelEntry[]
}

Expand All @@ -25,7 +25,6 @@ export interface RenderModelEntry {
rendered_query: string
}

// @eslint-disable-next-line @typescript-eslint/consistent-type-definition
export type CustomLSPMethods =
| AllModelsMethod
| AbstractAPICall
Expand All @@ -40,7 +39,7 @@ interface AllModelsRequest {
}
}

interface AllModelsResponse {
interface AllModelsResponse extends BaseResponse {
models: string[]
keywords: string[]
}
Expand All @@ -55,9 +54,11 @@ export interface AbstractAPICallRequest {
export interface AbstractAPICall {
method: 'sqlmesh/api'
request: AbstractAPICallRequest
response: object
response: AbstractAPICallResponse
}

type AbstractAPICallResponse = object & BaseResponse
Comment thread
benfdking marked this conversation as resolved.

export interface AllModelsForRenderMethod {
method: 'sqlmesh/all_models_for_render'
request: AllModelsForRenderRequest
Expand All @@ -67,7 +68,7 @@ export interface AllModelsForRenderMethod {
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
interface AllModelsForRenderRequest {}

interface AllModelsForRenderResponse {
interface AllModelsForRenderResponse extends BaseResponse {
models: ModelForRendering[]
}

Expand All @@ -87,7 +88,7 @@ export interface SupportedMethodsMethod {
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
interface SupportedMethodsRequest {}

interface SupportedMethodsResponse {
interface SupportedMethodsResponse extends BaseResponse {
methods: CustomMethod[]
}

Expand All @@ -105,4 +106,8 @@ export interface FormatProjectMethod {
interface FormatProjectRequest {}

// eslint-disable-next-line @typescript-eslint/no-empty-object-type
interface FormatProjectResponse {}
interface FormatProjectResponse extends BaseResponse {}

interface BaseResponse {
response_error?: string
}
3 changes: 3 additions & 0 deletions vscode/extension/src/lsp/lsp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,9 @@ export class LSPClient implements Disposable {

try {
const result = await this.client.sendRequest<Response>(method, request)
if (result.response_error) {
Comment thread
benfdking marked this conversation as resolved.
return err(result.response_error)
}
return ok(result)
} catch (error) {
traceError(
Expand Down
41 changes: 35 additions & 6 deletions vscode/extension/src/webviews/lineagePanel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
} from 'vscode'
import { getWorkspaceFolders } from '../utilities/common/vscodeapi'
import { LSPClient } from '../lsp/lsp'
import { isErr } from '@bus/result'

export class LineagePanel implements WebviewViewProvider, Disposable {
public static readonly viewType = 'sqlmesh.lineage'
Expand Down Expand Up @@ -97,12 +98,40 @@ export class LineagePanel implements WebviewViewProvider, Disposable {
'sqlmesh/api',
payload.params,
)
const responseCallback: CallbackEvent = {
key: 'rpcResponse',
payload: {
requestId,
result: response,
},
let responseCallback: CallbackEvent
if (isErr(response)) {
let errorMessage: string
switch (response.error.type) {
case 'generic':
errorMessage = response.error.message
break
case 'invalid_state':
Comment thread
benfdking marked this conversation as resolved.
errorMessage = `Invalid state: ${response.error.message}`
break
case 'sqlmesh_outdated':
errorMessage = `SQLMesh version issue: ${response.error.message}`
break
default:
errorMessage = 'Unknown error'
}
responseCallback = {
key: 'rpcResponse',
payload: {
requestId,
result: {
ok: false,
error: errorMessage,
},
},
}
} else {
responseCallback = {
key: 'rpcResponse',
payload: {
requestId,
result: response,
},
}
}
await webviewView.webview.postMessage(responseCallback)
break
Expand Down
36 changes: 36 additions & 0 deletions vscode/extension/tests/broken_project.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,3 +92,39 @@ test('bad project, double model, then fixed', async ({}) => {
await fs.remove(tempDir)
}
})

test('bad project, double model, check lineage', async ({}) => {
const tempDir = await fs.mkdtemp(
path.join(os.tmpdir(), 'vscode-test-tcloud-'),
)
await fs.copy(SUSHI_SOURCE_PATH, tempDir)

// Read the customers.sql file
const customersSql = await fs.readFile(
path.join(tempDir, 'models', 'customers.sql'),
'utf8',
)

// Write the customers.sql file with a double model
await fs.writeFile(
path.join(tempDir, 'models', 'customers_duplicated.sql'),
customersSql,
)

const { window, close } = await startVSCode(tempDir)
try {
await window.waitForSelector('text=models')

// Open the lineage view
await openLineageView(window)

await window.waitForSelector('text=Error creating context')

await window.waitForSelector('text=Error:')

await window.waitForTimeout(1000)
} finally {
await close()
await fs.remove(tempDir)
}
})
10 changes: 9 additions & 1 deletion vscode/react/src/pages/lineage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,11 @@ function Lineage() {
const { on } = useEventBus()
const queryClient = useQueryClient()

const { data: models, isLoading: isLoadingModels } = useApiModels()
const {
data: models,
isLoading: isLoadingModels,
error: modelsError,
} = useApiModels()
const rpc = useRpc()
React.useEffect(() => {
const fetchFirstTimeModelIfNotSet = async (
Expand Down Expand Up @@ -143,6 +147,10 @@ function Lineage() {
}
}, [on, queryClient, modelsRecord])

if (modelsError) {
return <div>Error: {modelsError.message}</div>
}

if (
isLoadingModels ||
models === undefined ||
Expand Down