Skip to content

Commit ca129b4

Browse files
Druuejkomyno
andauthored
Impr/logging (#1396)
* wasm logging * added toasts for wasm-errors formatting eslint * remove unnecessary unused-var rules * Updated naming scheme to use `onError` The variant will use it's own name in `server.ts` - to show what's being given, in this case `showErrorToast` * added check to prisma-fmt fns for debug panic * Added tests for wasm-panics Added missing onError for previews path Minor Refactor - Moved findCursorPosition * explicit undefined check for - compositeTypeFieldNames * Added comment for mock onError Added check for arg getting used * test(language-server): replaced assert.ok with assert.strictEqual * removed unnecessary typings --------- Co-authored-by: Alberto Schiabel <[email protected]> Co-authored-by: jkomyno <[email protected]>
1 parent 97f706f commit ca129b4

24 files changed

+647
-152
lines changed

.eslintrc.js

+10-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,16 @@ module.exports = {
2222
'plugin:@typescript-eslint/eslint-recommended',
2323
'plugin:@typescript-eslint/recommended-requiring-type-checking',
2424
],
25-
rules: {},
25+
rules: {
26+
'@typescript-eslint/no-unused-vars': [
27+
'warn', // or "error"
28+
{
29+
argsIgnorePattern: '^_',
30+
varsIgnorePattern: '^_',
31+
caughtErrorsIgnorePattern: '^_',
32+
},
33+
],
34+
},
2635
},
2736
],
2837
}

packages/language-server/src/MessageHandler.ts

+40-13
Original file line numberDiff line numberDiff line change
@@ -237,10 +237,18 @@ export function handleHoverRequest(document: TextDocument, params: HoverParams):
237237
return
238238
}
239239

240-
function prismaFmtCompletions(params: CompletionParams, document: TextDocument): CompletionList | undefined {
240+
function prismaFmtCompletions(
241+
params: CompletionParams,
242+
document: TextDocument,
243+
onError?: (errorMessage: string) => void,
244+
): CompletionList | undefined {
241245
const text = document.getText(fullDocumentRange(document))
242246

243-
const completionList = textDocumentCompletion(text, params)
247+
const completionList = textDocumentCompletion(text, params, (errorMessage: string) => {
248+
if (onError) {
249+
onError(errorMessage)
250+
}
251+
})
244252

245253
if (completionList.items.length === 0) {
246254
return undefined
@@ -249,7 +257,11 @@ function prismaFmtCompletions(params: CompletionParams, document: TextDocument):
249257
}
250258
}
251259

252-
function localCompletions(params: CompletionParams, document: TextDocument): CompletionList | undefined {
260+
function localCompletions(
261+
params: CompletionParams,
262+
document: TextDocument,
263+
onError?: (errorMessage: string) => void,
264+
): CompletionList | undefined {
253265
const context = params.context
254266
const position = params.position
255267

@@ -291,6 +303,7 @@ function localCompletions(params: CompletionParams, document: TextDocument): Com
291303
lines,
292304
wordsBeforePosition,
293305
document,
306+
onError,
294307
)
295308
case '"':
296309
return getSuggestionForSupportedFields(
@@ -299,17 +312,15 @@ function localCompletions(params: CompletionParams, document: TextDocument): Com
299312
currentLineUntrimmed,
300313
position,
301314
lines,
315+
onError,
302316
)
303317
case '.':
304318
// check if inside attribute
305319
// Useful to complete composite types
306-
if (
307-
['model', 'view'].includes(foundBlock.type) &&
308-
isInsideAttribute(currentLineUntrimmed, position, '()')
309-
) {
320+
if (['model', 'view'].includes(foundBlock.type) && isInsideAttribute(currentLineUntrimmed, position, '()')) {
310321
return getSuggestionsForInsideRoundBrackets(currentLineUntrimmed, lines, document, position, foundBlock)
311322
} else {
312-
return getSuggestionForNativeTypes(foundBlock, lines, wordsBeforePosition, document)
323+
return getSuggestionForNativeTypes(foundBlock, lines, wordsBeforePosition, document, onError)
313324
}
314325
}
315326
}
@@ -326,7 +337,14 @@ function localCompletions(params: CompletionParams, document: TextDocument): Com
326337
if (!positionIsAfterFieldAndType(position, document, wordsBeforePosition)) {
327338
return getSuggestionsForFieldTypes(foundBlock, lines, position, currentLineUntrimmed)
328339
}
329-
return getSuggestionForFieldAttribute(foundBlock, lines[position.line], lines, wordsBeforePosition, document)
340+
return getSuggestionForFieldAttribute(
341+
foundBlock,
342+
lines[position.line],
343+
lines,
344+
wordsBeforePosition,
345+
document,
346+
onError,
347+
)
330348
case 'datasource':
331349
case 'generator':
332350
if (wordsBeforePosition.length === 1 && symbolBeforePositionIsWhiteSpace) {
@@ -344,6 +362,7 @@ function localCompletions(params: CompletionParams, document: TextDocument): Com
344362
currentLineUntrimmed,
345363
position,
346364
lines,
365+
onError,
347366
)
348367
}
349368
break
@@ -356,8 +375,12 @@ function localCompletions(params: CompletionParams, document: TextDocument): Com
356375
*
357376
* This handler provides the initial list of the completion items.
358377
*/
359-
export function handleCompletionRequest(params: CompletionParams, document: TextDocument): CompletionList | undefined {
360-
return prismaFmtCompletions(params, document) || localCompletions(params, document)
378+
export function handleCompletionRequest(
379+
params: CompletionParams,
380+
document: TextDocument,
381+
onError?: (errorMessage: string) => void,
382+
): CompletionList | undefined {
383+
return prismaFmtCompletions(params, document, onError) || localCompletions(params, document, onError)
361384
}
362385

363386
export function handleRenameRequest(params: RenameParams, document: TextDocument): WorkspaceEdit | undefined {
@@ -453,12 +476,16 @@ export function handleCompletionResolveRequest(item: CompletionItem): Completion
453476
return item
454477
}
455478

456-
export function handleCodeActions(params: CodeActionParams, document: TextDocument): CodeAction[] {
479+
export function handleCodeActions(
480+
params: CodeActionParams,
481+
document: TextDocument,
482+
onError?: (errorMessage: string) => void,
483+
): CodeAction[] {
457484
if (!params.context.diagnostics.length) {
458485
return []
459486
}
460487

461-
return quickFix(document, params)
488+
return quickFix(document, params, onError)
462489
}
463490

464491
export function handleDocumentSymbol(params: DocumentSymbolParams, document: TextDocument): DocumentSymbol[] {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
export class WasmPanicRegistry {
2+
private message = ''
3+
4+
get() {
5+
return `${this.message}`
6+
}
7+
8+
// Don't use this method directly, it's only used by the Wasm panic hook in @prisma/prisma-fmt-wasm.
9+
private set_message(value: string) {
10+
this.message = `RuntimeError: ${value}`
11+
}
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,237 @@
1+
import { CodeActionParams, CompletionParams, DocumentFormattingParams } from 'vscode-languageserver'
2+
import { TextDocument } from 'vscode-languageserver-textdocument'
3+
import {
4+
handleCodeActions,
5+
handleCompletionRequest,
6+
handleDiagnosticsRequest,
7+
handleDocumentFormatting,
8+
} from '../MessageHandler'
9+
import { CURSOR_CHARACTER, findCursorPosition, getTextDocument } from './helper'
10+
11+
import * as assert from 'assert'
12+
13+
suite('Artificial Panics', () => {
14+
const OLD_ENV = { ...process.env }
15+
16+
test('code actions', () => {
17+
const fixturePath = './artificial-panic/schema.prisma'
18+
const document = getTextDocument(fixturePath)
19+
20+
const params: CodeActionParams = {
21+
textDocument: document,
22+
range: {
23+
start: { line: 0, character: 0 },
24+
end: { line: 0, character: 0 },
25+
},
26+
context: {
27+
diagnostics: [
28+
{
29+
range: {
30+
start: { line: 0, character: 0 },
31+
end: { line: 0, character: 0 },
32+
},
33+
message: 'dx msg',
34+
},
35+
],
36+
},
37+
}
38+
39+
process.env.FORCE_PANIC_PRISMA_FMT = '1'
40+
41+
let calledCount = 0
42+
let calledArg: undefined | unknown = undefined
43+
44+
// No official mock implementation in mocha
45+
// -> DIY mock for onError
46+
const onError = (arg: unknown) => {
47+
calledCount += 1
48+
calledArg = arg
49+
}
50+
51+
try {
52+
const _codeActions = handleCodeActions(params, document, onError)
53+
54+
assert.fail("This shouldn't happen!")
55+
} catch (e) {
56+
assert.ok(calledArg)
57+
assert.strictEqual(calledCount, 1)
58+
} finally {
59+
process.env = { ...OLD_ENV }
60+
}
61+
})
62+
63+
test('formatter', () => {
64+
const fixturePath = './artificial-panic/schema.prisma'
65+
const document = getTextDocument(fixturePath)
66+
67+
const params: DocumentFormattingParams = {
68+
textDocument: document,
69+
options: {
70+
tabSize: 2,
71+
insertSpaces: true,
72+
},
73+
}
74+
75+
process.env.FORCE_PANIC_PRISMA_FMT = '1'
76+
77+
let calledCount = 0
78+
let calledArg: undefined | unknown = undefined
79+
80+
const onError = (arg: unknown) => {
81+
calledCount += 1
82+
calledArg = arg
83+
}
84+
85+
try {
86+
const _formatResult = handleDocumentFormatting(params, document, onError)
87+
88+
assert.fail("This shouldn't happen!")
89+
} catch (e) {
90+
assert.ok(calledArg)
91+
assert.strictEqual(calledCount, 1)
92+
} finally {
93+
process.env = { ...OLD_ENV }
94+
}
95+
})
96+
97+
test('linting', () => {
98+
const fixturePath = './artificial-panic/schema.prisma'
99+
const document = getTextDocument(fixturePath)
100+
101+
process.env.FORCE_PANIC_PRISMA_FMT = '1'
102+
103+
let calledCount = 0
104+
let calledArg: undefined | unknown = undefined
105+
106+
const onError = (arg: unknown) => {
107+
calledCount += 1
108+
calledArg = arg
109+
}
110+
111+
try {
112+
const _diagnostics = handleDiagnosticsRequest(document, onError)
113+
114+
assert.fail("This shouldn't happen!")
115+
} catch (e) {
116+
assert.ok(calledArg)
117+
assert.strictEqual(calledCount, 1)
118+
} finally {
119+
process.env = { ...OLD_ENV }
120+
}
121+
})
122+
123+
test('preview features', () => {
124+
const fixturePath = './artificial-panic/schema.prisma'
125+
let document = getTextDocument(fixturePath)
126+
127+
const schema = document.getText()
128+
129+
const position = findCursorPosition(schema)
130+
131+
document = TextDocument.create(
132+
'./artificial-panic/schema.prisma',
133+
'prisma',
134+
1,
135+
schema.replace(CURSOR_CHARACTER, ''),
136+
)
137+
138+
const params: CompletionParams = {
139+
textDocument: document,
140+
position,
141+
}
142+
143+
process.env.FORCE_PANIC_PRISMA_FMT_LOCAL = '1'
144+
145+
let calledCount = 0
146+
let calledArg: undefined | unknown = undefined
147+
148+
const onError = (arg: unknown) => {
149+
calledCount += 1
150+
calledArg = arg
151+
}
152+
153+
try {
154+
const _completions = handleCompletionRequest(params, document, onError)
155+
156+
assert.fail("This shouldn't happen!")
157+
} catch (e) {
158+
assert.ok(calledArg)
159+
assert.strictEqual(calledCount, 1)
160+
} finally {
161+
process.env = { ...OLD_ENV }
162+
}
163+
})
164+
165+
test('native types', () => {
166+
const fixturePath = './artificial-panic/native-types.prisma'
167+
let document = getTextDocument(fixturePath)
168+
169+
const schema = document.getText()
170+
171+
const position = findCursorPosition(schema)
172+
173+
document = TextDocument.create(
174+
'./artificial-panic/native-types.prisma',
175+
'prisma',
176+
1,
177+
schema.replace(CURSOR_CHARACTER, ''),
178+
)
179+
180+
const params: CompletionParams = {
181+
textDocument: document,
182+
position,
183+
}
184+
185+
process.env.FORCE_PANIC_PRISMA_FMT_LOCAL = '1'
186+
187+
let calledCount = 0
188+
let calledArg: undefined | unknown = undefined
189+
190+
const onError = (arg: unknown) => {
191+
calledCount += 1
192+
calledArg = arg
193+
}
194+
195+
try {
196+
const _completions = handleCompletionRequest(params, document, onError)
197+
198+
assert.fail("This shouldn't happen!")
199+
} catch (e) {
200+
assert.ok(calledArg)
201+
assert.strictEqual(calledCount, 1)
202+
} finally {
203+
process.env = { ...OLD_ENV }
204+
}
205+
})
206+
207+
test('completions', () => {
208+
const fixturePath = './artificial-panic/schema.prisma'
209+
const document = getTextDocument(fixturePath)
210+
211+
const params: CompletionParams = {
212+
textDocument: document,
213+
position: { character: 0, line: 0 },
214+
}
215+
216+
process.env.FORCE_PANIC_PRISMA_FMT = '1'
217+
218+
let calledCount = 0
219+
let calledArg: undefined | unknown = undefined
220+
221+
const onError = (arg: unknown) => {
222+
calledCount += 1
223+
calledArg = arg
224+
}
225+
226+
try {
227+
const _completions = handleCompletionRequest(params, document, onError)
228+
229+
assert.fail("This shouldn't happen!")
230+
} catch (e) {
231+
assert.ok(calledArg)
232+
assert.strictEqual(calledCount, 1)
233+
} finally {
234+
process.env = { ...OLD_ENV }
235+
}
236+
})
237+
})

0 commit comments

Comments
 (0)