为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
肥皂起泡泡 2021-09-27 10:42:33
我有一个简短的 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 mainimport (    "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]stringtype 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)    }
查看完整描述

3 回答

?
慕无忌1623718

TA贡献1744条经验 获得超4个赞

首先,正如已评论的那样,您确定不能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因此不清楚它是否应该为空或由于前面的错误而为空。永远不要忽略错误返回!)


查看完整回答
反对 回复 2021-09-27
?
大话西游666

TA贡献1817条经验 获得超14个赞

我在 Go 程序中也遇到了同样的错误消息,但是当我的 HTTP 响应解析器期望 JSON 时,错误消息在 HTTP 响应错误中,采用 HTML 格式。

对我来说,解决方案是更改我的请求以包括将Content-Type标头设置为application/json. 您如何执行此操作取决于您碰巧使用的是哪个 http 客户端库;如果您有权访问http.Header核心类型,则可以使用.Set(...).

我意识到这个修复对我来说的范围可能不适用于最初的问题,但我在谷歌搜索后首先来到这里并认为这会帮助其他人,因为乍一看消息并不是特别明显。提示是无效<字符是错误/响应中的第一个 HTML 字符,这很可能是请求类型未设置为 的结果application/json,因此服务器以非 JSON 响应进行响应。


查看完整回答
反对 回复 2021-09-27
?
幕布斯7119047

TA贡献1794条经验 获得超8个赞

对我来说,问题是我试图解析已经解析的 JSON。


查看完整回答
反对 回复 2021-09-27
  • 3 回答
  • 0 关注
  • 265 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信