From 58a5226eb5a8b57ae0e16bdd1852fb41a2ae6736 Mon Sep 17 00:00:00 2001 From: BenBirt Date: Thu, 8 Aug 2019 14:44:44 +0200 Subject: [PATCH] Correctly report filenames in compilation Errors created in compile(). (#350) * Correctly report filenames in compilation Errors created in compile(). * fixes --- core/operation.ts | 3 ++- core/test.ts | 13 ++++++++--- core/utils.ts | 55 ++++++++++++++++++++++++----------------------- version.bzl | 2 +- 4 files changed, 41 insertions(+), 32 deletions(-) diff --git a/core/operation.ts b/core/operation.ts index 06844daf4..fb8b66993 100644 --- a/core/operation.ts +++ b/core/operation.ts @@ -95,7 +95,8 @@ export class Operation { this.session.compileError( new Error( "Actions of type 'operations' may only describe columns if they specify 'hasOutput: true'." - ) + ), + this.proto.fileName ); } diff --git a/core/test.ts b/core/test.ts index f69b9e660..e503612e1 100644 --- a/core/test.ts +++ b/core/test.ts @@ -42,14 +42,21 @@ export class Test { public compile() { const testContext = new TestContext(this); if (!this.datasetToTest) { - this.session.compileError(new Error("Tests must operate upon a specified dataset.")); + this.session.compileError( + new Error("Tests must operate upon a specified dataset."), + this.proto.fileName + ); } else { const dataset = this.session.tables[this.datasetToTest]; if (!dataset) { - this.session.compileError(new Error(`Dataset ${this.datasetToTest} could not be found.`)); + this.session.compileError( + new Error(`Dataset ${this.datasetToTest} could not be found.`), + this.proto.fileName + ); } else if (dataset.proto.type === "incremental") { this.session.compileError( - new Error("Running tests on incremental datasets is not yet supported.") + new Error("Running tests on incremental datasets is not yet supported."), + this.proto.fileName ); } else { const refReplacingContext = new RefReplacingContext(testContext); diff --git a/core/utils.ts b/core/utils.ts index faaa7b081..b859c3abb 100644 --- a/core/utils.ts +++ b/core/utils.ts @@ -41,36 +41,37 @@ export function matchPatterns(patterns: string[], values: string[]) { } export function getCallerFile(rootDir: string) { - const originalFunc = Error.prepareStackTrace; - let callerfile; - let lastfile; + let lastfile: string; + const stack = getCurrentStack(); + while (stack.length) { + lastfile = stack.shift().getFileName(); + if (!lastfile) { + continue; + } + if (!lastfile.includes(rootDir)) { + continue; + } + if (lastfile.includes("node_modules")) { + continue; + } + if (!(lastfile.includes("definitions/") || lastfile.includes("models/"))) { + continue; + } + break; + } + return relativePath(lastfile, rootDir); +} + +function getCurrentStack(): NodeJS.CallSite[] { + const originalPrepareStackTrace = Error.prepareStackTrace; try { - const err = new Error(); - let currentfile; - Error.prepareStackTrace = function(err, stack) { + Error.prepareStackTrace = (err, stack) => { return stack; }; - - currentfile = (err.stack as any).shift().getFileName(); - while (err.stack.length) { - callerfile = (err.stack as any).shift().getFileName(); - if (callerfile) { - lastfile = callerfile; - } - if ( - currentfile !== callerfile && - callerfile.includes(rootDir) && - !callerfile.includes("node_modules") && - // We don't want to attribute files in includes/ to the caller files. - (callerfile.includes("definitions/") || callerfile.includes("models/")) - ) { - break; - } - } - } catch (e) {} - Error.prepareStackTrace = originalFunc; - - return relativePath(callerfile || lastfile, rootDir); + return (new Error().stack as unknown) as NodeJS.CallSite[]; + } finally { + Error.prepareStackTrace = originalPrepareStackTrace; + } } export function graphHasErrors(graph: dataform.ICompiledGraph) { diff --git a/version.bzl b/version.bzl index e92ffa14e..bf797c30c 100644 --- a/version.bzl +++ b/version.bzl @@ -1,3 +1,3 @@ # NOTE: If you change the format of this line, you must change the bash command # in /scripts/publish to extract the version string correctly. -DF_VERSION = "1.1.1" +DF_VERSION = "1.1.2"