【问题标题】:Handling errors from base64 decode in Go在 Go 中处理来自 base64 解码的错误
【发布时间】:2017-07-02 21:42:15
【问题描述】:

考虑这个简单的base64解码sn-p:

package main

import (
    "fmt"
    "encoding/base64"
)

func main() {
    const encoded string = "aGVsbG8=" // hello
    decoded, err := base64.StdEncoding.DecodeString(encoded)
    if err != nil {
        panic(err)
    }
    fmt.Println(string(decoded))
}

这会按预期产生 hello。 现在,如果我故意传入损坏的输入,例如

const encoded string = "XXXXXaGVsbG8="

然后我点击了给我的恐慌线:

panic: illegal base64 data at input byte 11

goroutine 1 [running]:
main.main()
    /tmp/sandbox422941756/main.go:12 +0x140

查看source codethis issue,除了匹配字符串文字并向调用者返回更有意义的错误消息外,似乎没有什么可做的了:

if err != nil {
    if strings.Contains(err.Error(), "illegal base64 data at input byte") {
        panic("\nbase64 input is corrupt, check service Key")
    }
}

除了字符串匹配之外,必须有一种更优雅的方式来做到这一点。 go 式的实现方式是什么?

【问题讨论】:

    标签: go error-handling base64


    【解决方案1】:

    查看错误类型。例如,

    package main
    
    import (
        "encoding/base64"
        "fmt"
    )
    
    func main() {
        encoded := "XXXXXaGVsbG8=" // corrupt
        decoded, err := base64.StdEncoding.DecodeString(encoded)
        if err != nil {
            if _, ok := err.(base64.CorruptInputError); ok {
                panic("\nbase64 input is corrupt, check service Key")
            }
            panic(err)
        }
        fmt.Println(string(decoded))
    }
    

    输出:

    panic: 
    base64 input is corrupt, check service Key
    

    【讨论】:

    • 啊,是的,当然,错误在 Go 中有类型。我想先阅读手册,然后再提问。谢谢!
    【解决方案2】:

    查看实现(未导出的base64.Encoding.decode() 方法),如果该方法返回错误,则只能是具体类型base64.CorruptInputError。这种错误类型总是产生以下错误字符串:

    func (e CorruptInputError) Error() string {
        return "illegal base64 data at input byte " + strconv.FormatInt(int64(e), 10)
    }
    

    所以除了一些极端情况(如内存不足错误、修改执行代码等)如果base64.StdEncoding.DecodeString()返回错误,它的错误字符串将总是包含字符串"illegal base64 data at input byte "(在当前版本)。

    不需要检查其错误字符串,您可以将任何非nil返回的错误视为输入无效。错误字符串是一个实现细节,所以无论如何你都不应该依赖它。错误字符串是针对 humans 的,而不是针对 code 的。这就是 encoding/base64 包的实现方式,除此之外您无法进行任何更精细的错误处理(通常在 Encoding.DecodeString() 的情况下无需区分单独的错误情况)。

    当一个包确实为不同的错误情况提供了不同的错误值时,有一些技术可以很好地处理它们。有关详细信息,请查看以下问题:

    Does go have standard Err variables?

    如前所述,如果encoding/base64 包返回具体的base64.CorruptInputError 类型的值,您可以使用type assertion 进行检查。请参阅 peterSO 的答案。

    【讨论】:

    • 您依赖于特定时间点的特定实现。不要那样做。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-15
    • 1970-01-01
    • 2014-08-28
    • 2015-11-24
    • 2014-11-27
    • 2010-11-11
    相关资源
    最近更新 更多