如何在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

相关文章

go 指针接收者和值接收者的区别小结

《go指针接收者和值接收者的区别小结》在Go语言中,值接收者和指针接收者是方法定义中的两种接收者类型,本文主要介绍了go指针接收者和值接收者的区别小结,文中通过示例代码介绍的非常详细,需要的朋友们下... 目录go 指针接收者和值接收者的区别易错点辨析go 指针接收者和值接收者的区别指针接收者和值接收者的

Go 语言中的select语句详解及工作原理

《Go语言中的select语句详解及工作原理》在Go语言中,select语句是用于处理多个通道(channel)操作的一种控制结构,它类似于switch语句,本文给大家介绍Go语言中的select语... 目录Go 语言中的 select 是做什么的基本功能语法工作原理示例示例 1:监听多个通道示例 2:带

C/C++错误信息处理的常见方法及函数

《C/C++错误信息处理的常见方法及函数》C/C++是两种广泛使用的编程语言,特别是在系统编程、嵌入式开发以及高性能计算领域,:本文主要介绍C/C++错误信息处理的常见方法及函数,文中通过代码介绍... 目录前言1. errno 和 perror()示例:2. strerror()示例:3. perror(

Go标准库常见错误分析和解决办法

《Go标准库常见错误分析和解决办法》Go语言的标准库为开发者提供了丰富且高效的工具,涵盖了从网络编程到文件操作等各个方面,然而,标准库虽好,使用不当却可能适得其反,正所谓工欲善其事,必先利其器,本文将... 目录1. 使用了错误的time.Duration2. time.After导致的内存泄漏3. jsO

go中空接口的具体使用

《go中空接口的具体使用》空接口是一种特殊的接口类型,它不包含任何方法,本文主要介绍了go中空接口的具体使用,具有一定的参考价值,感兴趣的可以了解一下... 目录接口-空接口1. 什么是空接口?2. 如何使用空接口?第一,第二,第三,3. 空接口几个要注意的坑坑1:坑2:坑3:接口-空接口1. 什么是空接

Python中ModuleNotFoundError: No module named ‘timm’的错误解决

《Python中ModuleNotFoundError:Nomodulenamed‘timm’的错误解决》本文主要介绍了Python中ModuleNotFoundError:Nomodulen... 目录一、引言二、错误原因分析三、解决办法1.安装timm模块2. 检查python环境3. 解决安装路径问题

如何解决mysql出现Incorrect string value for column ‘表项‘ at row 1错误问题

《如何解决mysql出现Incorrectstringvalueforcolumn‘表项‘atrow1错误问题》:本文主要介绍如何解决mysql出现Incorrectstringv... 目录mysql出现Incorrect string value for column ‘表项‘ at row 1错误报错

利用Go语言开发文件操作工具轻松处理所有文件

《利用Go语言开发文件操作工具轻松处理所有文件》在后端开发中,文件操作是一个非常常见但又容易出错的场景,本文小编要向大家介绍一个强大的Go语言文件操作工具库,它能帮你轻松处理各种文件操作场景... 目录为什么需要这个工具?核心功能详解1. 文件/目录存javascript在性检查2. 批量创建目录3. 文件

一文详解SQL Server如何跟踪自动统计信息更新

《一文详解SQLServer如何跟踪自动统计信息更新》SQLServer数据库中,我们都清楚统计信息对于优化器来说非常重要,所以本文就来和大家简单聊一聊SQLServer如何跟踪自动统计信息更新吧... SQL Server数据库中,我们都清楚统计信息对于优化器来说非常重要。一般情况下,我们会开启"自动更新

Python如何获取域名的SSL证书信息和到期时间

《Python如何获取域名的SSL证书信息和到期时间》在当今互联网时代,SSL证书的重要性不言而喻,它不仅为用户提供了安全的连接,还能提高网站的搜索引擎排名,那我们怎么才能通过Python获取域名的S... 目录了解SSL证书的基本概念使用python库来抓取SSL证书信息安装必要的库编写获取SSL证书信息