Skip to content

Commit 7ad032d

Browse files
committed
Fix more uncaught errors
1 parent b83438b commit 7ad032d

File tree

9 files changed

+275
-201
lines changed

9 files changed

+275
-201
lines changed

src/commands/compile.ts

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ export async function importFile(
9292
ignoreConflict?: boolean,
9393
skipDeplCheck = false
9494
): Promise<any> {
95+
if (!file) return;
9596
const api = new AtelierAPI(file.uri);
9697
if (!api.active) return;
9798
if (file.name.split(".").pop().toLowerCase() === "cls" && !skipDeplCheck) {
@@ -261,6 +262,8 @@ export async function loadChanges(files: (CurrentTextFile | CurrentBinaryFile)[]
261262
}
262263

263264
export async function compile(docs: (CurrentTextFile | CurrentBinaryFile)[], flags?: string): Promise<any> {
265+
docs = docs.filter(notNull);
266+
if (!docs.length) return;
264267
const wsFolder = vscode.workspace.getWorkspaceFolder(docs[0].uri);
265268
const conf = vscode.workspace.getConfiguration("objectscript", wsFolder || docs[0].uri);
266269
flags = flags || conf.get("compileFlags");
@@ -437,18 +440,20 @@ async function importFiles(files: vscode.Uri[], noCompile = false) {
437440
rateLimiter.call(async () => {
438441
return vscode.workspace.fs
439442
.readFile(uri)
440-
.then((contentBytes) => {
441-
if (isText(uri.path.split("/").pop(), Buffer.from(contentBytes))) {
442-
const textFile = currentFileFromContent(uri, new TextDecoder().decode(contentBytes));
443-
toCompile.push(textFile);
444-
return textFile;
445-
} else {
446-
return currentFileFromContent(uri, Buffer.from(contentBytes));
443+
.then((contentBytes) =>
444+
currentFileFromContent(
445+
uri,
446+
isText(uri.path.split("/").pop(), Buffer.from(contentBytes))
447+
? new TextDecoder().decode(contentBytes)
448+
: Buffer.from(contentBytes)
449+
)
450+
)
451+
.then((curFile) => {
452+
if (curFile) {
453+
if (typeof curFile.content == "string") toCompile.push(curFile); // Only compile text files
454+
return importFile(curFile).then(() => outputChannel.appendLine("Imported file: " + curFile.fileName));
447455
}
448-
})
449-
.then((curFile) =>
450-
importFile(curFile).then(() => outputChannel.appendLine("Imported file: " + curFile.fileName))
451-
);
456+
});
452457
})
453458
)
454459
);

src/commands/connectFolderToServerNamespace.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ export async function connectFolderToServerNamespace(): Promise<void> {
4242
items.length === 1 && !items[0].detail
4343
? items[0]
4444
: await vscode.window.showQuickPick(items, { title: "Pick a folder" });
45+
if (!pick) return;
4546
const folder = vscode.workspace.workspaceFolders.find((el) => el.name === pick.label);
4647
// Get user's choice of server
4748
const options: vscode.QuickPickOptions = {};

src/commands/studio.ts

Lines changed: 58 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as vscode from "vscode";
22
import { AtelierAPI } from "../api";
33
import { iscIcon } from "../extension";
4-
import { outputChannel, outputConsole, notIsfs, handleError, openLowCodeEditors } from "../utils";
4+
import { outputChannel, outputConsole, notIsfs, handleError, openLowCodeEditors, stringifyError } from "../utils";
55
import { DocumentContentProvider } from "../providers/DocumentContentProvider";
66
import { UserAction } from "../api/atelier";
77
import { isfsDocumentName } from "../providers/FileSystemProvider/FileSystemProvider";
@@ -113,7 +113,7 @@ export class StudioActions {
113113
);
114114
}
115115

116-
public processUserAction(userAction: UserAction): Thenable<any> {
116+
public async processUserAction(userAction: UserAction): Promise<any> {
117117
const serverAction = userAction.action;
118118
const { target, errorText } = userAction;
119119
if (errorText !== "") {
@@ -128,7 +128,22 @@ export class StudioActions {
128128
return vscode.window
129129
.showWarningMessage(target, { modal: true }, "Yes", "No")
130130
.then((answer) => (answer === "Yes" ? "1" : answer === "No" ? "0" : "2"));
131-
case 2: // Run a CSP page/Template. The Target is the full path of CSP page/template on the connected server
131+
case 2: {
132+
// Run a CSP page/Template. The Target is the full path of CSP page/template on the connected server
133+
134+
// Do this ourself instead of using our new getCSPToken wrapper function, because that function reuses tokens which causes issues with
135+
// webview when server is 2020.1.1 or greater, as session cookie scope is typically Strict, meaning that the webview
136+
// cannot store the cookie. Consequence is web sessions may build up (they get a 900 second timeout)
137+
const cspchd = await this.api
138+
.actionQuery("select %Atelier_v1_Utils.General_GetCSPToken(?) token", [target])
139+
.then((data) => data.result.content[0].token)
140+
.catch((error) => {
141+
outputChannel.appendLine(
142+
`Failed to construct a CSP session for server-side source control User Action 2 (show a CSP page) on page '${target}': ${stringifyError(error)}\nReturning answer 2 (Cancel)`
143+
);
144+
outputChannel.show(true);
145+
});
146+
if (!cspchd) return "2";
132147
return new Promise((resolve) => {
133148
let answer = "2";
134149
const column = vscode.window.activeTextEditor ? vscode.window.activeTextEditor.viewColumn : undefined;
@@ -157,16 +172,10 @@ export class StudioActions {
157172
const url = new URL(
158173
`${config.https ? "https" : "http"}://${config.host}:${config.port}${config.pathPrefix}${target}`
159174
);
160-
161-
// Do this ourself instead of using our new getCSPToken wrapper function, because that function reuses tokens which causes issues with
162-
// webview when server is 2020.1.1 or greater, as session cookie scope is typically Strict, meaning that the webview
163-
// cannot store the cookie. Consequence is web sessions may build up (they get a 900 second timeout)
164-
this.api.actionQuery("select %Atelier_v1_Utils.General_GetCSPToken(?) token", [target]).then((tokenObj) => {
165-
const csptoken = tokenObj.result.content[0].token;
166-
url.searchParams.set("CSPCHD", csptoken);
167-
url.searchParams.set("CSPSHARE", "1");
168-
url.searchParams.set("Namespace", this.api.config.ns);
169-
panel.webview.html = `
175+
url.searchParams.set("CSPCHD", cspchd);
176+
url.searchParams.set("CSPSHARE", "1");
177+
url.searchParams.set("Namespace", this.api.ns);
178+
panel.webview.html = `
170179
<!DOCTYPE html>
171180
<html lang="en">
172181
<head>
@@ -194,18 +203,21 @@ export class StudioActions {
194203
</body>
195204
</html>
196205
`;
197-
});
198206
});
207+
}
199208
case 3: {
200209
// Run an EXE on the client.
201-
const urlRegex = /^(ht|f)tp(s?):\/\//gim;
202-
if (target.search(urlRegex) === 0) {
210+
if (/^(ht|f)tps?:\/\//i.test(target)) {
203211
// Allow target that is a URL to be opened in an external browser
204212
vscode.env.openExternal(vscode.Uri.parse(target));
205-
break;
206213
} else {
207-
throw new Error("processUserAction: Run EXE (Action=3) not supported");
214+
// Anything else is not supported
215+
outputChannel.appendLine(
216+
`Server-side source control User Action 3 (run an EXE on the client) is not supported for target '${target}'`
217+
);
218+
outputChannel.show(true);
208219
}
220+
break;
209221
}
210222
case 4: {
211223
// Insert the text in Target in the current document at the current selection point
@@ -219,39 +231,45 @@ export class StudioActions {
219231
}
220232
case 5: // Studio will open the documents listed in Target
221233
target.split(",").forEach((element) => {
222-
let classname: string = element;
234+
let fileName: string = element;
223235
let method: string;
224236
let offset = 0;
225237
if (element.includes(":")) {
226-
[classname, method] = element.split(":");
238+
[fileName, method] = element.split(":");
227239
if (method.includes("+")) {
228240
offset = +method.split("+")[1];
229241
method = method.split("+")[0];
230242
}
231243
}
232244

233-
const splitClassname = classname.split(".");
234-
const filetype = splitClassname[splitClassname.length - 1];
245+
const fileExt = fileName.split(".").pop().toLowerCase();
235246
const isCorrectMethod = (text: string) =>
236-
filetype === "cls" ? text.match("Method " + method) : text.startsWith(method);
237-
238-
const uri = DocumentContentProvider.getUri(classname);
239-
vscode.window.showTextDocument(uri, { preview: false }).then((newEditor) => {
240-
if (method) {
241-
const document = newEditor.document;
242-
for (let i = 0; i < document.lineCount; i++) {
243-
const line = document.lineAt(i);
244-
if (isCorrectMethod(line.text)) {
245-
if (!line.text.endsWith("{")) offset++;
246-
const targetLine = document.lineAt(i + offset);
247-
const range = new vscode.Range(targetLine.range.start, targetLine.range.start);
248-
newEditor.selection = new vscode.Selection(range.start, range.start);
249-
newEditor.revealRange(range, vscode.TextEditorRevealType.InCenter);
250-
break;
247+
fileExt === "cls" ? text.match("Method " + method) : text.startsWith(method);
248+
249+
vscode.window.showTextDocument(DocumentContentProvider.getUri(fileName), { preview: false }).then(
250+
(newEditor) => {
251+
if (method) {
252+
const document = newEditor.document;
253+
for (let i = 0; i < document.lineCount; i++) {
254+
const line = document.lineAt(i);
255+
if (isCorrectMethod(line.text)) {
256+
if (!line.text.endsWith("{")) offset++;
257+
const targetLine = document.lineAt(i + offset);
258+
const range = new vscode.Range(targetLine.range.start, targetLine.range.start);
259+
newEditor.selection = new vscode.Selection(range.start, range.start);
260+
newEditor.revealRange(range, vscode.TextEditorRevealType.InCenter);
261+
break;
262+
}
251263
}
252264
}
265+
},
266+
(error) => {
267+
outputChannel.appendLine(
268+
`Server-side source control User Action 5 failed to show '${element}': ${stringifyError(error)}`
269+
);
270+
outputChannel.show(true);
253271
}
254-
});
272+
);
255273
});
256274
break;
257275
case 6: // Display an alert dialog in Studio with the text from the Target variable.
@@ -268,7 +286,8 @@ export class StudioActions {
268286
};
269287
});
270288
default:
271-
throw new Error(`processUserAction: ${userAction} not supported`);
289+
outputChannel.appendLine(`Unknown server-side source control User Action ${serverAction} is not supported`);
290+
outputChannel.show(true);
272291
}
273292
return Promise.resolve();
274293
}

src/commands/viewOthers.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ export async function viewOthers(forceEditable = false): Promise<void> {
5353
const methodlinetext: string = doc.lineAt(methodlinenum).text.trim();
5454
if (methodlinetext.endsWith("{")) {
5555
// This is the last line of the method definition, so count from here
56-
const selectionline: number = methodlinenum + +loc.slice(loc.lastIndexOf("+") + 1);
56+
const selectionline: number = methodlinenum + (+loc.slice(loc.lastIndexOf("+") + 1) || 0);
5757
options.selection = new vscode.Range(selectionline, 0, selectionline, 0);
5858
break;
5959
}
@@ -68,7 +68,7 @@ export async function viewOthers(forceEditable = false): Promise<void> {
6868
loc = loc.slice(0, loc.lastIndexOf("+"));
6969
}
7070
// Locations in INT routines are of the format +offset
71-
const linenum: number = +loc.slice(1);
71+
const linenum: number = +loc.slice(1) || 0;
7272
options.selection = new vscode.Range(linenum, 0, linenum, 0);
7373
}
7474
vscode.window.showTextDocument(uri, options);

0 commit comments

Comments
 (0)