pb33f / libopenapi

libopenapi is a fully featured, high performance OpenAPI 3.1, 3.0 and Swagger parser, library, validator and toolkit for golang applications.
https://pb33f.io/libopenapi/
Other
482 stars 64 forks source link

Quickstart tutorial leads to `nil pointer dereference error` #308

Closed baderj closed 4 months ago

baderj commented 4 months ago

You are linking to Parsing OpenAPI files using go guide as the Quick-start tutorial for libopenapi.

Following the tutorial (while fixing the three different spellings of docModel, docmodel and model) leads to a panic: runtime error: invalid memory address or nil pointer dereference when printing the schemas. Steps to reproduce:

  1. curl https://raw.githubusercontent.com/OAI/OpenAPI-Specification/main/examples/v3.0/petstore.yaml > petstorev3.json
  2. go get github.com/pb33f/libopenapi
  3. Create this main.go file:
package main

import (
    "fmt"
    "os"

    "github.com/pb33f/libopenapi"
)

func main() {
    petstore, _ := os.ReadFile("petstorev3.json")
    document, err := libopenapi.NewDocument(petstore)
    if err != nil {
        panic(fmt.Sprintf("cannot create new document: %e", err))
    }
    docModel, errors := document.BuildV3Model()
    if len(errors) > 0 {
        for i := range errors {
            fmt.Printf("error: %e\n", errors[i])
        }
        panic(fmt.Sprintf("cannot create v3 model from document: %d errors reported", len(errors)))
    }

    // The following fails after the first iteration
    for schemaPairs := docModel.Model.Components.Schemas.First(); schemaPairs != nil; schemaPairs = schemaPairs.Next() {
        schemaName := schemaPairs.Key()
        schema := schemaPairs.Value()
        fmt.Printf("Schema '%s' has %d properties\n", schemaName, schema.Schema().Properties.Len())
    }
}
  1. go run main.go

This produces

Schema 'Pet' has 3 properties
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x7cbf4e]

goroutine 1 [running]:
main.main()
        /home/bug/main.go:28 +0x1ce
exit status 2

Tested with v0.16.10 of libopenapi and 1.0.0 of the Swagger Petstore specification.

This error is expected, as Pets does not have any properties as it is an array of Pet.

Maybe you could just add a small snippet as the quickstart guide instead of the the external tutorial.

daveshanley commented 4 months ago

Thank you for this work. I like your idea.

daveshanley commented 4 months ago

The code should read like this. I will update it and add to the quick start.

package main

import (
    "fmt"
    "github.com/pb33f/libopenapi"
    "os"
)

func main() {
    petstore, _ := os.ReadFile("petstorev3.json")
    document, err := libopenapi.NewDocument(petstore)
    if err != nil {
        panic(fmt.Sprintf("cannot create new document: %e", err))
    }
    docModel, errors := document.BuildV3Model()
    if len(errors) > 0 {
        for i := range errors {
            fmt.Printf("error: %e\n", errors[i])
        }
        panic(fmt.Sprintf("cannot create v3 model from document: %d errors reported", len(errors)))
    }

    // The following fails after the first iteration
    for schemaPairs := docModel.Model.Components.Schemas.First(); schemaPairs != nil; schemaPairs = schemaPairs.Next() {

        // get the name of the schema
        schemaName := schemaPairs.Key()

        // get the schema object from the map
        schemaValue := schemaPairs.Value()

        // build the schema
        schema := schemaValue.Schema()

        // if the schema has properties, print the number of properties
        if schema != nil && schema.Properties != nil {
            fmt.Printf("Schema '%s' has %d properties\n", schemaName, schema.Properties.Len())
        }
    }
}
daveshanley commented 4 months ago

Readme has been updated with this exact code walk through, thank you for the nudge.

Also the blog post has been updated.