Skip to content

Commit

Permalink
Merge pull request #478 from KxSystems/KXI-52672
Browse files Browse the repository at this point in the history
KXI-52672 Show stack trace on errors against Insights scratchpad
  • Loading branch information
nfarrell-kx authored Dec 16, 2024
2 parents 3699b56 + 1cbc79e commit 3a6b752
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 3 deletions.
21 changes: 18 additions & 3 deletions src/commands/serverCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,11 @@ import { refreshDataSourcesPanel } from "../utils/dataSource";
import { decodeQUTF } from "../utils/decode";
import { ExecutionConsole } from "../utils/executionConsole";
import { openUrl } from "../utils/openUrl";
import { checkIfIsDatasource, addQueryHistory } from "../utils/queryUtils";
import {
checkIfIsDatasource,
addQueryHistory,
formatScratchpadStacktrace,
} from "../utils/queryUtils";
import {
validateServerAlias,
validateServerName,
Expand Down Expand Up @@ -1184,9 +1188,20 @@ export function writeScratchpadResult(
duration: string,
connVersion: number,
): void {
let errorMsg;

if (result.error) {
errorMsg = result.errorMsg;

if (result.stacktrace) {
errorMsg =
errorMsg + "\n" + formatScratchpadStacktrace(result.stacktrace);
}
}

if (ext.isResultsTabVisible) {
writeQueryResultsToView(
result.error ? result.errorMsg : result,
errorMsg ?? result,
query,
connLabel,
executorName,
Expand All @@ -1199,7 +1214,7 @@ export function writeScratchpadResult(
);
} else {
writeQueryResultsToConsole(
result.error ? result.errorMsg : result.data,
errorMsg ?? result.data,
query,
connLabel,
executorName,
Expand Down
9 changes: 9 additions & 0 deletions src/models/scratchpadResult.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,18 @@
* specific language governing permissions and limitations under the License.
*/

type StacktraceItem = {
isNested: boolean;
name: string;
text: string[];
};

export type ScratchpadStacktrace = StacktraceItem[];

export type ScratchpadResult = {
data: string;
error: boolean;
errorMsg: string;
sessionID: string;
stacktrace?: ScratchpadStacktrace;
};
33 changes: 33 additions & 0 deletions src/utils/queryUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { DataSourceFiles, DataSourceTypes } from "../models/dataSource";
import { QueryHistory } from "../models/queryHistory";
import { kdbOutputLog } from "./core";
import { ServerType } from "../models/connectionsModels";
import { ScratchpadStacktrace } from "../models/scratchpadResult";

export function sanitizeQuery(query: string): string {
if (query[0] === "`") {
Expand Down Expand Up @@ -360,3 +361,35 @@ export function addQueryHistory(

ext.queryHistoryProvider.refresh();
}

export function formatScratchpadStacktrace(stacktrace: ScratchpadStacktrace) {
return stacktrace
.map((frame, i) => {
let lines = frame.text[0].split("\n");
let preline = "";
// We need to account for the possibility that the error
// occurs in a piece of code containing newlines, so we split
// up the text into lines and inject the caret into the correct
// location.
preline = lines.pop() as string;
const caretline = Array(preline.length).fill(" ").join("") + "^";
const postlines = (preline + frame.text[1]).split("\n");
postlines.splice(1, 0, caretline);
lines = lines.concat(postlines);

// main line of trace
let str = "[" + (stacktrace.length - 1 - i) + "] " + frame.name;

// add indicator for nested anonymous functions
if (frame.isNested) {
str += " @ ";
}

// add gutter to align other lines with the first one
const gutter = " ".repeat(str.length);
str += lines.map((l, i) => (i > 0 ? gutter + l : l)).join("\n");

return str;
})
.join("\n");
}
28 changes: 28 additions & 0 deletions test/suite/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -901,6 +901,34 @@ describe("Utils", () => {
);
assert.strictEqual(ext.kdbQueryHistoryList.length, 1);
});

it("should format a Scratchpad stacktrace correctly", () => {
const stacktrace = [
{ name: "g", isNested: false, text: ["{a:x*2;a", "+y}"] },
{ name: "f", isNested: false, text: ["{", "g[x;2#y]}"] },
{ name: "", isNested: false, text: ["", 'f[3;"hello"]'] },
];

const formatted = queryUtils.formatScratchpadStacktrace(stacktrace);
assert.strictEqual(
formatted,
'[2] g{a:x*2;a+y}\n ^\n[1] f{g[x;2#y]}\n ^\n[0] f[3;"hello"]\n ^',
);
});

it("should format a Scratchpad stacktrace with nested function correctly", () => {
const stacktrace = [
{ name: "f", isNested: true, text: ["{a:x*2;a", "+y}"] },
{ name: "f", isNested: false, text: ["{", "{a:x*2;a+y}[x;2#y]}"] },
{ name: "", isNested: false, text: ["", 'f[3;"hello"]'] },
];

const formatted = queryUtils.formatScratchpadStacktrace(stacktrace);
assert.strictEqual(
formatted,
'[2] f @ {a:x*2;a+y}\n ^\n[1] f{{a:x*2;a+y}[x;2#y]}\n ^\n[0] f[3;"hello"]\n ^',
);
});
});

describe("selectDSType", () => {
Expand Down

0 comments on commit 3a6b752

Please sign in to comment.