如何查找、"invalid character ',' looking for beginning of value"错误消息



>我有一个简短的Go程序,它为多个包运行go list -json命令,将每次命令运行的输出存储在json中。RawMessage,附加每个 json。RawMessage 成一片 json。RawMessages,然后在连接每个 json 后将结果返回到服务器。将原始消息组合在一起并压缩 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)
    }
    var buff bytes.Buffer
    //concatenate the separate json.RawMessages together into json
    buff.WriteByte('[')
    for i, j := range t.J {
        if i != 0 {
            buff.WriteByte(',')
        }
        buff.Write([]byte(j))
    }
    buff.WriteByte(']')
    var buffer bytes.Buffer
    if err := json.Compact(&buffer, buff.Bytes()); err != nil {
        println(err.Error()) //error message: invalid character ',' looking for beginning of value
        return
    }
    w.Header().Set("Content-Type", contentTypeJSON)
    w.Write(buffer.Bytes())
}
func (myObj *myType) imports(pk string) error {
    cmd := exec.Command("go", "list", "-json", pk)
    stdout, _ := cmd.Output()
    pack[pk] = pk
    var deplist Import
    json.Unmarshal(stdout, &deplist)
    var newj json.RawMessage
    json.Unmarshal(stdout, &newj)
    myObj.J = append(myObj.J, newj)
    for _, imp := range deplist.Imports {
        if _, ok := pack[imp]; !ok {
            myObj.imports(imp) //recursive call to get the imports of the imports etc
        }
    }
    return nil
}

首先,正如已经评论的那样,您确定不能使用直接go/build包而不是运行go list

我不会在HTTP处理程序中使用println(或fmt.Println(。最好使用log.Println和/或将错误放入ResponseWriter。此外,最好用 log.Fatal 包装您的ListenAndServe通话。

打印/记录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的错误,因此不清楚它是否应该为空,或者由于前面的错误而为空。永远不要忽略错误返回!

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

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

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

对我来说

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

我也遇到了这个错误"无效字符'N'寻找值的开头"。此错误是在"将非 json 响应解组为 json "时出现的。我期待一个 json 响应,所以编写了 go 代码将其解组为 json。但是,由于URL更改,我得到的响应是文本,即。"404 未找到"错误,无法将其解组为 json。"查找值开头的字符'N'无效">

因此,总而言之,当我们尝试将非 json 响应(text/html/xml(解组为 json 时,会出现此错误。

此令人

毛骨悚然的错误消息的原因是:

// When unmarshaling quoted strings, invalid UTF-8 or
// invalid UTF-16 surrogate pairs are not treated as an error.
// Instead, they are replaced by the Unicode replacement
// character U+FFFD.

https://golang.org/src/encoding/json/decode.go

就我而言,我将我的 json 保存为字符串,然后通过以下方式解析它: stringData = JSON.parse(myJsonString)

我再次使用gin-context-ShouldBind(((https://godoc.org/github.com/gin-gonic/gin#Context.ShouldBind(并将我的json映射到go对象时也遇到了同样的错误:错误是因为它需要一个 json 作为字符串,所以我在从前端部分发送请求时使用 : JSON.stringify(jsonObject(。

如果有人和我有同样的问题,我需要在我的帖子数据上调用 JSON.stringify。

我遇到了类似的问题,我的错误消息是:

查找值开头的无效字符"I">

就我而言,我试图使用 json.Unmarshal 解码BSON。Json 无法识别导致此错误的ISODate类型。

我也有类似的问题。对我来说,我省略了授权令牌的第一个字母。所以而不是

"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6InJhcGhhZWxuZ0BlbWFpbC5jb20iLCJleHAiOjE2MTM5NTQzMjB9.yPGC937VNAF8Qg05Z1x3fZ3zu_MUs-cA_Iag5-4RcJE"

我用了这个

"yJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6InJhcGhhZWxuZ0BlbWFpbC5jb20iLCJleHAiOjE2MTM5NTQzMjB9.yPGC937VNAF8Qg05Z1x3fZ3zu_MUs-cA_Iag5-4RcJE"

相关内容

最新更新