如何在Go中向错误中添加额外的信息

2023-12-19 12:04
文章标签 go 错误 信息 额外 中向

本文主要是介绍如何在Go中向错误中添加额外的信息,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

引言

当Go中的函数失败时,该函数将使用error接口返回一个值,以允许调用者处理该失败。在许多情况下,开发人员将使用fmt包中的fmt.Errorf函数来返回这些值。不过,在Go 1.13之前,使用此函数的一个缺点是,您将丢失有关可能导致错误返回的任何错误的信息。为了解决这个问题,开发人员要么使用包来提供一种方法将错误“包装”在其他错误中,要么通过在他们的struct错误类型上实现Error() string方法来创建自定义错误。然而,如果您有许多不需要由调用者显式处理的错误,有时创建这些struct类型可能会很繁琐,因此在Go 1.13中,语言添加了一些功能来更容易处理这些情况。

其中一个功能是能够使用带有error值的fmt.Errorf函数包装错误,该函数稍后可以展开以访问包装后的错误。这将错误包装功能构建到Go标准库中,因此不再需要使用第三方库。

此外,函数errors.Iserrors.As使确定特定错误是否包装在给定错误中的任何位置更容易,还将使您直接访问特定错误,而无需自己拆封所有错误。

在本教程中,你将创建一个程序,使用这些函数在函数返回的错误中包含额外的信息,然后创建你自己的自定义错误struct,以支持包装和解包装功能。

Go中的返回和处理错误

当程序中发生错误时,最好的做法是处理这些错误,让用户永远不会看到它们——但要处理这些错误,你需要首先了解它们。在Go中,你可以通过使用特殊的interface类型(即error接口)从函数中返回有关错误的信息来处理程序中的错误。使用error接口允许任何Go类型作为error值返回,只要该类型定义了Error() string方法。Go标准库提供了为这些返回值创建error的功能,例如fmt.Errorf函数。

在本节中,你将创建一个带有函数的程序,该函数使用fmt.Errorf来返回一个错误,你还将添加一个错误处理程序来检查函数可能返回的错误。如果您想了解有关Go中处理错误的更多信息,请参阅教程,Go中处理错误

许多开发人员都有一个目录来保存当前项目。在本教程中,你将使用一个名为projects的目录。

首先,创建projects目录并导航到它:

mkdir projects
cd projects

projects目录中,创建一个新的errtutorial目录来保存新程序:

mkdir errtutorial

接下来,使用cd命令切换到新目录:

cd errtutorial

进入errtutorial目录后,使用go mod init命令创建一个名为==errtutorial==的新模块:

go mod init errtutorial

创建Go模块后,使用nano或你喜欢的编辑器在errtutorial目录中打开一个名为main.go的文件:

nano main.go

接下来,你将编写一个程序。程序将循环遍历数字13,并使用名为validateValue的函数尝试确定这些数字是否有效。如果数字被确定为无效,程序将使用fmt.Errorf函数生成一个error值并从函数返回。fmt.Errorf函数允许你创建一个error值,其中的错误消息就是你提供给函数的消息。它的工作原理类似于fmt.Printf,但它不是将消息打印到屏幕上,而是将其作为error返回。

然后,在main函数中,将检查错误值是否为nil。如果是nil值,则函数成功并打印valid!消息。如果不是,则打印接收到的错误。

要开始你的程序,将以下代码添加到main.go文件中:

projects/errtutorial/main.go

package mainimport ("fmt"
)func validateValue(number int) error {if number == 1 {return fmt.Errorf("that's odd")} else if number == 2 {return fmt.Errorf("uh oh")}return nil
}func main() {for num := 1; num <= 3; num++ {fmt.Printf("validating %d... ", num)err := validateValue(num)if err != nil {fmt.Println("there was an error:", err)} else {fmt.Println("valid!")}}
}

程序中的validateValue函数接受一个数字,然后根据它是否被确定为有效值返回一个error。在这个程序中,数字1是无效的,并返回错误that's odd。数字2无效,并返回错误uh ohvalidateValue函数使用fmt.Errorf函数来生成要返回的error值。fmt.Errorf函数很方便地返回错误,因为它允许您使用类似于fmt.Printffmt.Sprintf的格式来格式化错误消息,而不需要将string传递给errors.New

main函数中,for循环将开始迭代从13的每个数字,并将值存储在num变量中。在循环体中,调用fmt.Printf将打印程序当前正在验证的数字。然后,它将调用validateValue函数并传入当前正在验证的数字num,并将错误结果存储在err变量中。最后,如果err不是nil,则意味着在验证过程中发生了错误,并使用fmt.Println打印错误消息。错误检查的else子句将打印"valid!"当没有遇到错误时。

保存更改后,使用go run命令运行程序,并将main.go作为errtutorial目录的参数:

go run main.go

运行该程序的输出将表明,对每个数字都运行了验证,数字1和数字2都返回了相应的错误:

Outputvalidating 1... there was an error: that's odd
validating 2... there was an error: uh oh
validating 3... valid!

查看程序的输出时,你会发现程序试图验证所有三个数字。第一次它说validateValue函数返回了that's odd错误,这是1的值所期望的。下一个值2也显示它返回了一个错误,但这次是uh oh错误。最后,3返回nil作为错误值,这意味着没有错误并且数字是有效的。根据validateValue函数的编写方式,任何非12的值都会返回nil错误值。

在本节中,你使用fmt.Errorf来创建从函数返回的error值。我们还添加了一个错误处理程序,以便在函数返回任何error时打印出错误消息。不过,有时候,知道错误的含义可能很有用,而不仅仅是知道错误发生了。在下一节中,你将学习针对特定情况自定义错误处理。

使用哨兵错误处理特定错误

当你从函数中收到一个error值时,最基本的错误处理是检查error值是否为nil。这将告诉你函数是否有错误,但有时你可能希望针对特定的错误情况自定义错误处理。例如,假设你有代码连接到远程服务器,而你得到的唯一错误信息是“you had a error”。你可能想知道这个错误是因为服务器不可用还是连接凭据无效。如果你知道这个错误意味着用户的凭据是错误的,你可能想让用户立即知道。但是,如果错误意味着服务器不可用,您可能需要尝试重新连接几次,然后才能让用户知道。确定这些错误之间的区别可以让你编写更健壮、更友好的程序。

检查特定类型错误的一种方法可能是使用error类型的error方法从错误中获取消息,并将该值与你要查找的错误类型进行比较。想象一下,在你的程序中,当错误值为uh oh时,你想显示一条消息,而不是 there was an error: uh oh。处理这种情况的一种方法是检查Error方法的返回值,如下所示:

if err.Error() == "uh oh" {// Handle 'uh oh' error.fmt.Println("oh no!")
}

检查err.Error()的字符串值,看看它是否为uh oh,就像上面的代码一样,在这种情况下可以工作。但是,如果程序中其他地方的uh oh错误字符串稍有不同,代码就无法工作。检查错误如果需要更新错误消息本身,这种方式也可能导致对代码的重大更新,因为每个检查错误的地方都需要更新。以以下代码为例:

func giveMeError() error {return fmt.Errorf("uh h")
}err := giveMeError</

这篇关于如何在Go中向错误中添加额外的信息的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/512093

相关文章

如何解决Druid线程池Cause:java.sql.SQLRecoverableException:IO错误:Socket read timed out的问题

《如何解决Druid线程池Cause:java.sql.SQLRecoverableException:IO错误:Socketreadtimedout的问题》:本文主要介绍解决Druid线程... 目录异常信息触发场景找到版本发布更新的说明从版本更新信息可以看到该默认逻辑已经去除总结异常信息触发场景复

Python struct.unpack() 用法及常见错误详解

《Pythonstruct.unpack()用法及常见错误详解》struct.unpack()是Python中用于将二进制数据(字节序列)解析为Python数据类型的函数,通常与struct.pa... 目录一、函数语法二、格式字符串详解三、使用示例示例 1:解析整数和浮点数示例 2:解析字符串示例 3:解

CentOS 7 YUM源配置错误的解决方法

《CentOS7YUM源配置错误的解决方法》在使用虚拟机安装CentOS7系统时,我们可能会遇到YUM源配置错误的问题,导致无法正常下载软件包,为了解决这个问题,我们可以替换YUM源... 目录一、备份原有的 YUM 源配置文件二、选择并配置新的 YUM 源三、清理旧的缓存并重建新的缓存四、验证 YUM 源

Linux查看系统盘和SSD盘的容量、型号及挂载信息的方法

《Linux查看系统盘和SSD盘的容量、型号及挂载信息的方法》在Linux系统中,管理磁盘设备和分区是日常运维工作的重要部分,而lsblk命令是一个强大的工具,它用于列出系统中的块设备(blockde... 目录1. 查看所有磁盘的物理信息方法 1:使用 lsblk(推荐)方法 2:使用 fdisk -l(

Go语言中使用JWT进行身份验证的几种方式

《Go语言中使用JWT进行身份验证的几种方式》本文主要介绍了Go语言中使用JWT进行身份验证的几种方式,包括dgrijalva/jwt-go、golang-jwt/jwt、lestrrat-go/jw... 目录简介1. github.com/dgrijalva/jwt-go安装:使用示例:解释:2. gi

SpringBoot如何对密码等敏感信息进行脱敏处理

《SpringBoot如何对密码等敏感信息进行脱敏处理》这篇文章主要为大家详细介绍了SpringBoot对密码等敏感信息进行脱敏处理的几个常用方法,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下... 目录​1. 配置文件敏感信息脱敏​​2. 日志脱敏​​3. API响应脱敏​​4. 其他注意事项​​总结

go rate 原生标准限速库的使用

《gorate原生标准限速库的使用》本文主要介绍了Go标准库golang.org/x/time/rate实现限流,采用令牌桶算法控制请求速率,提供Allow/Reserve/Wait方法,具有一定... 目录介绍安装API介绍rate.NewLimiter:创建限流器limiter.Allow():请求是否

python3 pip终端出现错误解决的方法详解

《python3pip终端出现错误解决的方法详解》这篇文章主要为大家详细介绍了python3pip如果在终端出现错误该如何解决,文中的示例方法讲解详细,感兴趣的小伙伴可以跟随小编一起了解一下... 目录前言一、查看是否已安装pip二、查看是否添加至环境变量1.查看环境变量是http://www.cppcns

Go 语言中的 Struct Tag 的用法详解

《Go语言中的StructTag的用法详解》在Go语言中,结构体字段标签(StructTag)是一种用于给字段添加元信息(metadata)的机制,常用于序列化(如JSON、XML)、ORM映... 目录一、结构体标签的基本语法二、json:"token"的具体含义三、常见的标签格式变体四、使用示例五、使用

python进行while遍历的常见错误解析

《python进行while遍历的常见错误解析》在Python中选择合适的遍历方式需要综合考虑可读性、性能和具体需求,本文就来和大家讲解一下python中while遍历常见错误以及所有遍历方法的优缺点... 目录一、超出数组范围问题分析错误复现解决方法关键区别二、continue使用问题分析正确写法关键点三