猿问

如何查找“无效字符 ',' 正在寻找值的开头”错误消息

我有一个简短的 Go 程序,它运行go list -json多个包的命令,将命令每次运行的输出存储在 json.RawMessage 中,将每个 json.RawMessage 附加到 json.RawMessages 的一部分中,然后将结果返回到服务器在将每个 json.RawMessages 连接在一起并压缩 json 之后。但是,运行时会生成一条错误消息,json.Compact但无法找到其来源。谷歌搜索此错误消息表明,大多数似乎遇到它的人 - 无论是无效的,还是其他一些角色 - 都很难找到它的来源。


invalid character ',' looking for beginning of value

带有注释的代码可以在 play.golang.org 上查看(虽然它不会在那里运行),也可以在下面查看。


问题:你能解释一下这个错误的来源以及如何预防吗?


(请注意,某些软件包仅用于测试目的)


package main


import (

    "expvar"


    "encoding/json"


    "bytes"

    "fmt"

    "github.com/go-martini/martini"

    "github.com/zenazn/goji"

    "github.com/zenazn/goji/web"

    "go/build"

    "log"

    "math/rand"

    "net/http"

    _ "net/http/pprof"

    "os/exec"

)


type myType struct {

    J []json.RawMessage

}


var pack map[string]string


type GoList struct {

    Imports []string

}


type Import struct {

    Dir        string

    ImportPath string

    Name       string

    Target     string

    Standard   bool

    Root       string

    GoFiles    []string

    Imports    []string

    Deps       []string

}


const contentTypeJSON = "application/json"


func main() {


    http.HandleFunc("/importgraph", func(w http.ResponseWriter, r *http.Request) { importGraph(w, r) })

    http.HandleFunc("/", handler)

    http.ListenAndServe(":8080", nil)


}


func handler(w http.ResponseWriter, r *http.Request) {

    fmt.Println("Inside handler")

    fmt.Fprintf(w, "Hello world from my Go program!")

}


func importGraph(w http.ResponseWriter, r *http.Request) {


    pack = make(map[string]string)


    var t myType

    cmd := exec.Command("go", "list", "-json")

    stdout, err := cmd.Output()

    if err != nil {


        println(err.Error())

        return

    }


    var list GoList

    err = json.Unmarshal(stdout, &list)


    for _, d := range list.Imports {

        //get the imports for each of the packages listed by go list -json

        t.imports(d)


    }


肥皂起泡泡
浏览 266回答 3
3回答

慕无忌1623718

首先,正如已评论的那样,您确定不能go/build直接使用该包而不是运行go list吗?我不会在 HTTP 处理程序中使用println(或fmt.Println)。使用log.Println和/或将错误放入ResponseWriter. 此外,最好ListenAndServe用log.Fatal.打印/记录error值时,您可以只使用err,无需使用err.Error().此外,当您实际上想要做一些比报告/记录错误消息更详细的事情时,您可以查看它的类型和其他信息。例如,log.Printf("verbose error info: %#v", err)给出:&json.SyntaxError{msg:"invalid character ',' looking for beginning of value", Offset:0}我试过这个是因为我知道json包返回各种错误类型和附加信息,我希望偏移值会有所帮助。如果是这样,那么这样的事情可能会有所帮助:if err := json.Compact(…) {    if err != nil {        log.Println("json.Compact:", err)        if serr, ok := err.(*json.SyntaxError); ok {            log.Println("Occurred at offset:", serr.Offset)            // … something to show the data in buff around that offset …        }    }}但偏移零没有帮助:(因此,尽管这不能确定您的问题,但希望它可以对您的进一步调查有所帮助。编辑:所以添加后:log.Println("Write file:", ioutil.WriteFile("data.json", buff.Bytes(), 0600))对于上面的错误处理块,我然后在结果文件上运行了一个 JSON 验证器,它识别了这一部分:        "XTestImports": [                "io",                "log",                "net"        ]},,{        "Dir": "/usr/local/go/src/mime",        "ImportPath": "mime",        "Name": "mime",注意双,,.这应该告诉您代码中的错误是什么。但如果没有,您需要在处理t.J或构建时跳过空条目。后者更好,只涉及:    if len(newj) > 0 {        myObj.J = append(myObj.J, newj)    }(顺便说一句,您不检查错误,json.Unmarshal因此不清楚它是否应该为空或由于前面的错误而为空。永远不要忽略错误返回!)

大话西游666

我在 Go 程序中也遇到了同样的错误消息,但是当我的 HTTP 响应解析器期望 JSON 时,错误消息在 HTTP 响应错误中,采用 HTML 格式。对我来说,解决方案是更改我的请求以包括将Content-Type标头设置为application/json.&nbsp;您如何执行此操作取决于您碰巧使用的是哪个 http 客户端库;如果您有权访问http.Header核心类型,则可以使用.Set(...).我意识到这个修复对我来说的范围可能不适用于最初的问题,但我在谷歌搜索后首先来到这里并认为这会帮助其他人,因为乍一看消息并不是特别明显。提示是无效<字符是错误/响应中的第一个 HTML 字符,这很可能是请求类型未设置为 的结果application/json,因此服务器以非 JSON 响应进行响应。

幕布斯7119047

对我来说,问题是我试图解析已经解析的 JSON。
随时随地看视频慕课网APP

相关分类

Go
我要回答