首页 文章

防止bson.ObjectIdHex中的运行时混乱

提问于
浏览
1

我正在尝试使用mgo将objectid字符串转换为bson ObjectId格式,

errCheck := d.C("col").FindId(bson.ObjectIdHex(obid[0])).One(&Result)

idk为什么,但如果我给错误/无效的输入字符串,我的应用程序得到运行时恐慌

我怎么能防止这种情况?谢谢

2 回答

  • 1

    bson.ObjectIdHex()文件如果你传递了无效的对象id,它会发生恐慌:

    ObjectIdHex从提供的十六进制表示中返回ObjectId . 使用无效的十六进制表示调用此函数将导致运行时混乱 . 请参阅IsObjectIdHex函数 .

    如果要避免这种情况,请首先使用bson.IsObjectIdHex()检查输入字符串,如果输入有效,则仅继续调用 bson.ObjectIdHex()

    if bson.IsObjectIdHex(obid[0]) {
        // It's valid, calling bson.ObjectIdHex() will not panic...
    }
    
  • 0

    正如@icza在最后一个回答中所说 . 你应该检查ObjectId的有效性 . 并且您可以使用panic recover defer来处理任何类型的错误

    package main
    
    import (
        "fmt"
        "gopkg.in/mgo.v2/bson"
        "path/filepath"
        "runtime"
        "strings"
    )
    
    func main() {
        r := Result{}
        getData(&r)
    }
    
    func IdentifyPanic() string {
        var name, file string
        var line int
        var pc [16]uintptr
    
        n := runtime.Callers(3, pc[:])
        for _, pc := range pc[:n] {
            fn := runtime.FuncForPC(pc)
            if fn == nil {
                continue
            }
            file, line = fn.FileLine(pc)
            name = fn.Name()
    
            if !strings.HasPrefix(name, "runtime.") {
                break
            }
        }
        file = filepath.Base(file)
    
        switch {
        case name != "":
            return fmt.Sprintf("%v:%v", file, line)
        case file != "":
            return fmt.Sprintf("%v:%v", file, line)
        }
    
        return fmt.Sprintf("pc:%x", pc)
    }
    
    type Result struct {
        success int
        data string
    }
    func getData(result *Result){
        defer func() {
            if err := recover(); err != nil {
                ip := IdentifyPanic()
                errorMessage := fmt.Sprintf("%s Error: %s", ip, err)
                fmt.Println(errorMessage)
                result.success = 0
            }
        }()
        if bson.IsObjectIdHex(obid[0]) {                                 // this line copied from @icza answer
            // It's valid, calling bson.ObjectIdHex() will not panic...  // this line copied from @icza answer
            errCheck := d.C("col").FindId(bson.ObjectIdHex(obid[0])).One(&res)
            result.success = 1
            result.data = "your result (res). this is just the exam"
        }else{
            result.success = 0  
        }
    }
    

相关问题