go-console icon indicating copy to clipboard operation
go-console copied to clipboard

Panic: nil pointer in getCellWidth: `t.output.Formatter()`

Open finicu212 opened this issue 2 years ago • 2 comments

Hi, so I'm trying to use the new JSON to Table functionality, and for some reason, when building a script as a go_console.Command I get a panic.

Here is an example:

func panicMain() {
	script := go_console.Command{
		Scripts: []*go_console.Script{
			{
				Name: "test",
				Runner: func(cmd *go_console.Script) go_console.ExitCode {
					tb := table.NewTable().SetParseMaxDepth(10).ParseJSON(getJsonBytes())
					for _, i := range tb.GetRows().GetRows() {
						fmt.Println(i)
					}
					rdr := table.NewRender(cmd.Output).SetContent(tb)
					rdr.Render()
					return go_console.ExitSuccess
				},
			},
		},
	}
	script.Run()
}

func main() {
	cmd := go_console.NewScript().Build()

	jsonData := getJsonBytes()

	tab := table.
		NewTable().
		ParseJSON(jsonData)

	render := table.
		NewRender(cmd.Output).
		SetContent(tab)

	render.Render()
}

func getJsonBytes() []byte {
	str := `{
      "type": "record"
    }`
	return []byte(str)
}

main is directly taken from example and works fine

panicMain has the following panic:

> go run .\main.go test
&{map[0:0xc0000666f0]}
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0x20 pc=0x517c5c]

goroutine 1 [running]:
github.com/DrSmithFr/go-console/table.(*TableRender).getCellWidth(0xc000076460, {0x5887e8?, 0xc00000a130?}, 0x0?)
        C:/Users/Finicu/go/pkg/mod/github.com/!dr!smith!fr/[email protected]/table/table-render.go:859 +0x7c
github.com/DrSmithFr/go-console/table.(*TableRender).calculateColumnsWidth(0xc000076460, 0xc000123a50)
        C:/Users/Finicu/go/pkg/mod/github.com/!dr!smith!fr/[email protected]/table/table-render.go:834 +0x246
github.com/DrSmithFr/go-console/table.(*TableRender).Render(0xc000076460)
        C:/Users/Finicu/go/pkg/mod/github.com/!dr!smith!fr/[email protected]/table/table-render.go:202 +0x17a
main.main.func1(0xc000136000)
        C:/Users/Finicu/GolandProjects/cli/main.go:20 +0x24c
github.com/DrSmithFr/go-console.(*Script).Build(0xc000136000)
        C:/Users/Finicu/go/pkg/mod/github.com/!dr!smith!fr/[email protected]/go-script.go:184 +0x6f
github.com/DrSmithFr/go-console.(*Command).Run(0xc000123df0)
        C:/Users/Finicu/go/pkg/mod/github.com/!dr!smith!fr/[email protected]/go-command.go:269 +0x57f
main.main()
        C:/Users/Finicu/GolandProjects/cli/main.go:26 +0x105
exit status 2

When tracking down the stack trace, I arrive at this line: https://github.com/DrSmithFr/go-console/blob/master/table/table-render.go#L859 and indeed, printing t.output.Formatter() seems to indicate it is nil.

I tried fixing this by manually setting script.Output = output.NewBufferedOutput(true, formatter.NewOutputFormatter()) before script.Run() but still get the same panic. I'm not too sure if this is caused by the way my configuration is setup or is a bug.

I was wondering if Run would be able to handle nil configs by itself and set some defaults? What do you think of that?

finicu212 avatar Jul 16 '23 16:07 finicu212

ahh. My bad, I managed to fix it: Basically, both script and each of the Scripts within script can have an Output. Setting the script.Output didn't seem to do much, and was panicking. But, setting the output of the individual script item (i.e. script.Scripts[0].Output for instance) actually fixes this problem.

But, it's a bit unusual to have these fields duplicated both on parent and on child object. I was thinking that, if script.Scripts[0].Output is nil, then it would look for a valid Object from its parent, script.Output

finicu212 avatar Jul 16 '23 16:07 finicu212

Hi,

Thanks for the return, indeed the output wasn't proprely cascaded from Command to Child Scripts instances. It's solved with the 1.4.1.

Your example work properly now.

To give you more detail of the internal process:

  • if you did not defined the Output (or set it to nil) on your instance of go_console.Command, it will generated for you the default ConsoleOutput (calling NewCliOutput(true, nil)).
  • if you did defined the Output on your instance of go_console.Command, it will be set as default Output for all childs Script. (note: you still can overwrite the Script output inside your runner func)

DrSmithFr avatar Jul 17 '23 10:07 DrSmithFr