Skip to content

Bad Source Map (again) #1845

@johndeighan

Description

@johndeighan

Consider the following civet program:

func2 := (): void =>
	throw new Error('bad')
	return


func1 := (): void =>
	func2()
	return


func1()

I intentionally added the blank lines because it illustrates the problem. I should also mention that if I remove all the blank lines, the problem goes away. When I compile it, I get this TypeScript file:

"use strict";
const func2 = (): void => {
	throw new Error('bad')
	return
}


const func1 = (): void => {
	func2()
	return
}


func1()

//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3JjL3RlbXAvdGhyb3cuY2l2ZXQudHN4Iiwic291cmNlcyI6WyJzcmMvdGVtcC90aHJvdy5jaXZldCJdLCJtYXBwaW5ncyI6IjtBQUFLLE1BQUwsS0FBSyxDQUFDLENBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUEsQ0FBQTtBQUNwQixBQUFBLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDO0FBQ3ZCLEFBQUEsQ0FBQyxNO0FBQU0sQ0FBQTtBQUNQLEFBQUE7QUFDQSxBQUFBO0FBQ0EsQUFBQSxBQUFLLE1BQUwsS0FBSyxDQUFDLENBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUEsQ0FBQTtBQUNwQixBQUFBLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDUixBQUFBLENBQUMsTTtBQUFNLENBQUE7QUFDUCxBQUFBO0FBQ0EsQUFBQTtBQUNBLEFBQUEsQUFBQSxLQUFLLENBQUMsQ0FBQztBQUNQIiwibmFtZXMiOltdLCJzb3VyY2VzQ29udGVudCI6WyJmdW5jMiA6PSAoKTogdm9pZCA9PlxuXHR0aHJvdyBuZXcgRXJyb3IoJ2JhZCcpXG5cdHJldHVyblxuXG5cbmZ1bmMxIDo9ICgpOiB2b2lkID0+XG5cdGZ1bmMyKClcblx0cmV0dXJuXG5cblxuZnVuYzEoKVxuIl19

(Sorry about including the long source map)
Now, the intention is obviously to throw an exception. The reason is to obtain the stack trace. I can run this TypeScript file 2 ways - using node or using deno. As you'll see, deno actually follows the source map while node does not. The line numbers in the node output are correct, but of course in the TypeScript file. The line numbers in the deno output, however, are wrong. Here are the 2 outputs:

Using node:

$ node src/temp/throw.ts
file:///C:/Users/johnd/util/src/temp/throw.ts:3
        throw new Error('bad')
              ^

Error: bad
    at func2 (file:///C:/Users/johnd/util/src/temp/throw.ts:3:8)
    at func1 (file:///C:/Users/johnd/util/src/temp/throw.ts:9:2)
    at file:///C:/Users/johnd/util/src/temp/throw.ts:14:1
    at ModuleJob.run (node:internal/modules/esm/module_job:413:25)
    at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader:6
60:26)
    at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:101
:5)

Node.js v24.12.0

Using deno:

$ deno run -A src/temp/throw.ts
error: Uncaught (in promise) Error: bad
    at func2 (file:///C:/Users/johnd/util/src/temp/src/temp/throw.civet:2:8)
    at func1 (file:///C:/Users/johnd/util/src/temp/src/temp/throw.civet:5:1)
    at file:///C:/Users/johnd/util/src/temp/src/temp/throw.civet:8:1

So, deno is telling me that the flow is from line 8, to line 5, to line 2, which is way off. Just look at the civet file.

I read somewhere that some people, when they generate a source map, mistakenly collapse whitespace. I don't know if that is the source of the problem or not. It's also possible that the problem lies with deno itself. I doubt that since, apparently, deno lets the V8 engine handle everything. Another thing I don't know is which versions of the V8 engine node and deno use. They might be different. If not, then clearly deno is handling the following of the source map part - probably delegating to some library. It's also possible that deno is using a newer version of the V8 engine which does the mapping.

FYI, I'm using Windows 11 - the latest, and my node , deno, and civet versions:

$ node --version
v24.12.0

$ deno --version
deno 2.6.7 (stable, release, x86_64-pc-windows-msvc)
v8 14.5.201.2-rusty
typescript 5.9.2

$ civet --version
0.11.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions