Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(code-editor): support source location navigation for panic messages #1225

Merged
merged 1 commit into from
Feb 18, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 64 additions & 17 deletions spx-gui/src/components/editor/preview/InPlaceRunner.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { ref, watch } from 'vue'
import { untilNotNull } from '@/utils/utils'
import ProjectRunner from '@/components/project/runner/ProjectRunner.vue'
import { useEditorCtx } from '../EditorContextProvider.vue'
import { RuntimeOutputKind } from '@/models/runtime'
import { RuntimeOutputKind, type RuntimeOutput } from '@/models/runtime'
import { getCleanupSignal } from '@/utils/disposable'

const props = defineProps<{
Expand All @@ -12,23 +12,26 @@ const props = defineProps<{

const editorCtx = useEditorCtx()
const projectRunnerRef = ref<InstanceType<typeof ProjectRunner>>()
const lastPanicOutput = ref<RuntimeOutput | null>(null)

function handleConsole(type: 'log' | 'warn', args: unknown[]) {
if (type === 'log' && args.length === 1 && typeof args[0] === 'string') {
try {
// Log format is determined by `github.com/goplus/builder/tools/ispx/main.go:logWithCallerInfo`.
//
// Example:
// {
// "time": "2025-01-14T11:50:34.808+08:00",
// "level": "INFO",
// "msg": "Hello, world!\n",
// "function": "main.(*MySprite).Main.func1",
// "file": "MySprite.spx",
// "line": 2
// }
const logMsg = JSON.parse(args[0])

// Handle info messages.
if (logMsg.level === 'INFO') {
// Log format is determined by `github.com/goplus/builder/tools/ispx/main.go:logWithCallerInfo`.
//
// Example:
// {
// "time": "2006-01-02T15:04:05Z07:00",
// "level": "INFO",
// "msg": "Hello, world!\n",
// "function": "main.(*MySprite).Main.func1",
// "file": "MySprite.spx",
// "line": 2
// }
editorCtx.runtime.addOutput({
kind: RuntimeOutputKind.Log,
time: logMsg.time,
Expand All @@ -45,16 +48,60 @@ function handleConsole(type: 'log' | 'warn', args: unknown[]) {
})
return
}

// Handle panic messages.
if (logMsg.level === 'ERROR' && logMsg.error && logMsg.msg === 'panic') {
// Log format is determined by `github.com/goplus/builder/tools/ispx/main.go:logWithPanicInfo`.
//
// Example:
// {
// "time": "2006-01-02T15:04:05Z07:00",
// "level": "ERROR",
// "msg": "captured panic",
// "error": "runtime error: index out of range [0] with length 0",
// "function": "main.(*MySprite).Main.func1",
// "file": "MySprite.spx",
// "line": 3,
// "column": 18
// }
lastPanicOutput.value = {
kind: RuntimeOutputKind.Error,
time: logMsg.time,
message: `panic: ${logMsg.error}`,
source: {
textDocument: {
uri: `file:///${logMsg.file}`
},
range: {
start: { line: logMsg.line, column: logMsg.column },
end: { line: logMsg.line, column: logMsg.column }
}
}
}
return
}
} catch {
// If parsing fails, fall through to default handling.
}
}

editorCtx.runtime.addOutput({
kind: type === 'warn' ? RuntimeOutputKind.Error : RuntimeOutputKind.Log,
time: Date.now(),
message: args.join(' ')
})
const message = args.join(' ')
if (/^panic: .+ \[recovered\]$/.test(message)) return

if (
type === 'log' &&
lastPanicOutput.value != null &&
(message === lastPanicOutput.value.message || message === '\t' + lastPanicOutput.value.message)
) {
editorCtx.runtime.addOutput(lastPanicOutput.value)
lastPanicOutput.value = null
} else {
editorCtx.runtime.addOutput({
kind: type === 'warn' ? RuntimeOutputKind.Error : RuntimeOutputKind.Log,
time: Date.now(),
message
})
}
}

watch(
Expand Down
2 changes: 2 additions & 0 deletions tools/ispx/embedded_pkgs.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//go:build js && wasm

package main

//go:generate go run github.com/goplus/igop/cmd/qexp@latest -outdir pkg github.com/goplus/spx
Expand Down
14 changes: 7 additions & 7 deletions tools/ispx/go.mod
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
module github.com/goplus/builder/ispx

go 1.21
go 1.21.0

require (
github.com/goplus/igop v0.29.0
github.com/goplus/reflectx v1.2.2
github.com/goplus/spx v1.1.1-0.20250205081831-c3f6e69289be
github.com/goplus/igop v0.32.0
github.com/goplus/reflectx v1.3.2
github.com/goplus/spx v1.1.1-0.20250214074125-e9e1f6362499
github.com/hajimehoshi/ebiten/v2 v2.8.0-alpha.3
)

Expand All @@ -20,13 +20,13 @@ require (
github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00 // indirect
github.com/goplus/canvas v0.1.0 // indirect
github.com/goplus/gogen v1.16.6 // indirect
github.com/goplus/gop v1.2.6 // indirect
github.com/goplus/mod v0.13.16 // indirect
github.com/goplus/gop v1.3.0 // indirect
github.com/goplus/mod v0.13.17 // indirect
github.com/hajimehoshi/go-mp3 v0.3.4 // indirect
github.com/jezek/xgb v1.1.1 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/qiniu/audio v0.2.1 // indirect
github.com/qiniu/x v1.13.11 // indirect
github.com/qiniu/x v1.13.12 // indirect
github.com/srwiley/oksvg v0.0.0-20210519022825-9fc0c575d5fe // indirect
github.com/srwiley/rasterx v0.0.0-20210519020934-456a8d69b780 // indirect
github.com/timandy/routine v1.1.4 // indirect
Expand Down
19 changes: 10 additions & 9 deletions tools/ispx/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,18 @@ github.com/goplus/gogen v1.16.6 h1:Zwv18HoTbPDk8s2ajxgVeqZE5i4/GMV722KHl6GS8Yk=
github.com/goplus/gogen v1.16.6/go.mod h1:6TQYbabXDF9LCdDkOOzHmfg1R4ENfXQ3XpHa9RhTSD8=
github.com/goplus/gop v1.2.0-pre.1.0.20250112163018-5fb12b1b2972 h1:wA4+I+DDfoNwR+zCnaeckt5pxZgLAuaKvVkC+T9GdiQ=
github.com/goplus/gop v1.2.0-pre.1.0.20250112163018-5fb12b1b2972/go.mod h1:lcW75c0a5v361jId1Vxs4lRrsasWsQDH0k3dG3Z7wH0=
github.com/goplus/igop v0.29.0 h1:25QmbeCLE9At14kd17xSpqP8Xg17Qqz3aGbOwiSfwiY=
github.com/goplus/igop v0.29.0/go.mod h1:V5P0rL4XmOUtAyJAPwYkLjsTZj8r47rO9UMZ+7Djycs=
github.com/goplus/igop v0.32.0 h1:2m/RjkkFLPzRJ0ERyNCh8Abk0XuLSlxFkEFaygnpHgM=
github.com/goplus/igop v0.32.0/go.mod h1:GCJA4qASZ1IU8MNNgDiW+Yf+eKf2G8fJWrx3arSBm8A=
github.com/goplus/llgo v0.9.9/go.mod h1:udcq+s6tGOdhJq7I8fXPTv4qT2j17/KrlvtcJrMZAoM=
github.com/goplus/llvm v0.8.0/go.mod h1:PeVK8GgzxwAYCiMiUAJb5wJR6xbhj989tu9oulKLLT4=
github.com/goplus/mod v0.13.13/go.mod h1:invR72Rz2+qpOOsXqxz830MX8/aR2GDR2EAow/WgfHI=
github.com/goplus/mod v0.13.15/go.mod h1:invR72Rz2+qpOOsXqxz830MX8/aR2GDR2EAow/WgfHI=
github.com/goplus/mod v0.13.16 h1:tiRk0jszPc66Oh+KBtMZUiTChG9ixzaI4vt7ZZ31HoU=
github.com/goplus/mod v0.13.16/go.mod h1:BsKIBf4PU1am5EgGtA2NV3+/W9cbzWu+9+dwGKj0pgk=
github.com/goplus/reflectx v1.2.2 h1:T1p20OIH/HcnAvQQNnDLwl6AZOjU34icsfc6migD6L8=
github.com/goplus/reflectx v1.2.2/go.mod h1:wHOS9ilbB4zrecI0W1dMmkW9JMcpXV7VjALVbNU9xfM=
github.com/goplus/spx v1.1.1-0.20250205081831-c3f6e69289be h1:Gfq4iShKChb7zQreePqekbAQN+3Ow6Qk8qWOTk1cmTY=
github.com/goplus/spx v1.1.1-0.20250205081831-c3f6e69289be/go.mod h1:JjIaVaDVnFasm/bkNHqvtKbd4i1sWScgAf5zPpz4HDw=
github.com/goplus/mod v0.13.17 h1:aWp14xosENrh7t0/0qcIejDmQEiTgI3ou2+KoLDlSlE=
github.com/goplus/mod v0.13.17/go.mod h1:XlHf8mnQ4QkRDX14Of2tpywuHDd+JVpPStvh3egog+0=
github.com/goplus/reflectx v1.3.2 h1:M6JBeENB8CB0F3FnlCpLtIqhAkluuVbCYHFzSrCLF9w=
github.com/goplus/reflectx v1.3.2/go.mod h1:wHOS9ilbB4zrecI0W1dMmkW9JMcpXV7VjALVbNU9xfM=
github.com/goplus/spx v1.1.1-0.20250214074125-e9e1f6362499 h1:wt9bXZWSZ6MKgLw0c87GSbKrXjj69aCt7JVM1RwLp3c=
github.com/goplus/spx v1.1.1-0.20250214074125-e9e1f6362499/go.mod h1:ng8mGU/k+1pXjG5zpeczzLOyDD0RhvOv35bxmpiTPGQ=
github.com/hajimehoshi/ebiten/v2 v2.8.0-alpha.3 h1:cKpQdzW3I+iLID68l25GaxzPZHSZVRdE9/Pz4SOPBR8=
github.com/hajimehoshi/ebiten/v2 v2.8.0-alpha.3/go.mod h1:iKp1U/H0J0rv9X4ztGSTXCyN6z/DKKrUL+D9sjg7SbI=
github.com/hajimehoshi/go-mp3 v0.3.2/go.mod h1:qMJj/CSDxx6CGHiZeCgbiq2DSUkbK0UbtXShQcnfyMM=
Expand All @@ -66,8 +66,9 @@ github.com/qiniu/oksvg v0.2.0-no-charset h1:KKQg81v52pd5VyaxrF891igoOO50epKfFWkr
github.com/qiniu/oksvg v0.2.0-no-charset/go.mod h1:YCAOS1HFo2kMxfcFCjrJMeo93KGFYaBAKl7LvrAkltQ=
github.com/qiniu/x v1.11.5/go.mod h1:03Ni9tj+N2h2aKnAz+6N0Xfl8FwMEDRC2PAlxekASDs=
github.com/qiniu/x v1.13.10/go.mod h1:INZ2TSWSJVWO/RuELQROERcslBwVgFG7MkTfEdaQz9E=
github.com/qiniu/x v1.13.11 h1:zlFLY9zFXOwKEjx0SQXRBunhFjDVpEY+pRGL/4shd5U=
github.com/qiniu/x v1.13.11/go.mod h1:INZ2TSWSJVWO/RuELQROERcslBwVgFG7MkTfEdaQz9E=
github.com/qiniu/x v1.13.12 h1:UyAwja6dgKUOYWZMzzc02wLodwnZ7wmK/0XzRd0e78g=
github.com/qiniu/x v1.13.12/go.mod h1:INZ2TSWSJVWO/RuELQROERcslBwVgFG7MkTfEdaQz9E=
github.com/srwiley/rasterx v0.0.0-20200120212402-85cb7272f5e9/go.mod h1:mvWM0+15UqyrFKqdRjY6LuAVJR0HOVhJlEgZ5JWtSWU=
github.com/srwiley/rasterx v0.0.0-20210519020934-456a8d69b780 h1:oDMiXaTMyBEuZMU53atpxqYsSB3U1CHkeAu2zr6wTeY=
github.com/srwiley/rasterx v0.0.0-20210519020934-456a8d69b780/go.mod h1:mvWM0+15UqyrFKqdRjY6LuAVJR0HOVhJlEgZ5JWtSWU=
Expand Down
14 changes: 14 additions & 0 deletions tools/ispx/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,18 @@ func logWithCallerInfo(msg string, frame *igop.Frame) {
}
}

func logWithPanicInfo(info *igop.PanicInfo) {
position := info.Position()
logger.Error(
"panic",
"error", info.Error,
"function", info.String(),
"file", position.Filename,
"line", position.Line,
"column", position.Column,
)
}

func main() {
js.Global().Set("goLoadData", js.FuncOf(loadData))

Expand All @@ -67,6 +79,8 @@ func main() {
return
}

ctx.SetPanic(logWithPanicInfo)

// NOTE(everyone): Keep sync with the config in spx [gop.mod](https://github.com/goplus/spx/blob/main/gop.mod)
gopbuild.RegisterClassFileType(".spx", "Game", []*gopbuild.Class{{Ext: ".spx", Class: "SpriteImpl"}}, "github.com/goplus/spx")

Expand Down
4 changes: 2 additions & 2 deletions tools/spxls/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ require (
github.com/goplus/gogen v1.16.6
github.com/goplus/gop v1.2.0-pre.1.0.20250112163018-5fb12b1b2972
github.com/goplus/mod v0.13.15
github.com/goplus/spx v1.1.1-0.20241231062359-381fc67db3e1
github.com/goplus/spx v1.1.1-0.20250214074125-e9e1f6362499
github.com/stretchr/testify v1.9.0
golang.org/x/tools v0.23.0
)
Expand All @@ -27,7 +27,7 @@ require (
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/qiniu/audio v0.2.1 // indirect
github.com/qiniu/x v1.13.11 // indirect
github.com/qiniu/x v1.13.12 // indirect
github.com/srwiley/oksvg v0.0.0-20210519022825-9fc0c575d5fe // indirect
github.com/srwiley/rasterx v0.0.0-20210519020934-456a8d69b780 // indirect
golang.org/x/image v0.18.0 // indirect
Expand Down
8 changes: 4 additions & 4 deletions tools/spxls/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ github.com/goplus/gop v1.2.0-pre.1.0.20250112163018-5fb12b1b2972 h1:wA4+I+DDfoNw
github.com/goplus/gop v1.2.0-pre.1.0.20250112163018-5fb12b1b2972/go.mod h1:lcW75c0a5v361jId1Vxs4lRrsasWsQDH0k3dG3Z7wH0=
github.com/goplus/mod v0.13.15 h1:IyneSjwm1VpwvHGz6hSHnFxZCuO6ULHcu74IAZcW9nw=
github.com/goplus/mod v0.13.15/go.mod h1:invR72Rz2+qpOOsXqxz830MX8/aR2GDR2EAow/WgfHI=
github.com/goplus/spx v1.1.1-0.20241231062359-381fc67db3e1 h1:JpAWB4m+LYjEIZwKMVvIeKqqvIjbcLYTXkkvU92Vbkk=
github.com/goplus/spx v1.1.1-0.20241231062359-381fc67db3e1/go.mod h1:1hkX9vPdDHrsA6LG8itiLMp83KIDJ0KlJI9CmpCoiCA=
github.com/goplus/spx v1.1.1-0.20250214074125-e9e1f6362499 h1:wt9bXZWSZ6MKgLw0c87GSbKrXjj69aCt7JVM1RwLp3c=
github.com/goplus/spx v1.1.1-0.20250214074125-e9e1f6362499/go.mod h1:ng8mGU/k+1pXjG5zpeczzLOyDD0RhvOv35bxmpiTPGQ=
github.com/hajimehoshi/ebiten/v2 v2.7.9 h1:DYH/usAa9dMHcGkBIIEApJsVqDekrJBxYHmsBuly8Iw=
github.com/hajimehoshi/ebiten/v2 v2.7.9/go.mod h1:Ulbq5xDmdx47P24EJ+Mb31Zps7vQq+guieG9mghQUaA=
github.com/hajimehoshi/go-mp3 v0.3.2/go.mod h1:qMJj/CSDxx6CGHiZeCgbiq2DSUkbK0UbtXShQcnfyMM=
Expand All @@ -46,8 +46,8 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/qiniu/audio v0.2.1 h1:lAc3dWfr7uAfn7mfee2u0/fl/QSQA9oTOqdBtxyFZAM=
github.com/qiniu/audio v0.2.1/go.mod h1:APMJRPaS4toviejZnDzzZ8wVyr12jqZhd3xfKr/qYnE=
github.com/qiniu/x v1.11.5/go.mod h1:03Ni9tj+N2h2aKnAz+6N0Xfl8FwMEDRC2PAlxekASDs=
github.com/qiniu/x v1.13.11 h1:zlFLY9zFXOwKEjx0SQXRBunhFjDVpEY+pRGL/4shd5U=
github.com/qiniu/x v1.13.11/go.mod h1:INZ2TSWSJVWO/RuELQROERcslBwVgFG7MkTfEdaQz9E=
github.com/qiniu/x v1.13.12 h1:UyAwja6dgKUOYWZMzzc02wLodwnZ7wmK/0XzRd0e78g=
github.com/qiniu/x v1.13.12/go.mod h1:INZ2TSWSJVWO/RuELQROERcslBwVgFG7MkTfEdaQz9E=
github.com/srwiley/oksvg v0.0.0-20210519022825-9fc0c575d5fe h1:J5Ga/gb+4/WgJBupg9Fp8F6JQnUT3UF+asoTweLi9Jc=
github.com/srwiley/oksvg v0.0.0-20210519022825-9fc0c575d5fe/go.mod h1:afMbS0qvv1m5tfENCwnOdZGOF8RGR/FsZ7bvBxQGZG4=
github.com/srwiley/rasterx v0.0.0-20210519020934-456a8d69b780 h1:oDMiXaTMyBEuZMU53atpxqYsSB3U1CHkeAu2zr6wTeY=
Expand Down
Loading