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

相关文章

部署Vue项目到服务器后404错误的原因及解决方案

《部署Vue项目到服务器后404错误的原因及解决方案》文章介绍了Vue项目部署步骤以及404错误的解决方案,部署步骤包括构建项目、上传文件、配置Web服务器、重启Nginx和访问域名,404错误通常是... 目录一、vue项目部署步骤二、404错误原因及解决方案错误场景原因分析解决方案一、Vue项目部署步骤

Python如何实现PDF隐私信息检测

《Python如何实现PDF隐私信息检测》随着越来越多的个人信息以电子形式存储和传输,确保这些信息的安全至关重要,本文将介绍如何使用Python检测PDF文件中的隐私信息,需要的可以参考下... 目录项目背景技术栈代码解析功能说明运行结php果在当今,数据隐私保护变得尤为重要。随着越来越多的个人信息以电子形

在MySQL执行UPDATE语句时遇到的错误1175的解决方案

《在MySQL执行UPDATE语句时遇到的错误1175的解决方案》MySQL安全更新模式(SafeUpdateMode)限制了UPDATE和DELETE操作,要求使用WHERE子句时必须基于主键或索引... mysql 中遇到的 Error Code: 1175 是由于启用了 安全更新模式(Safe Upd

Go路由注册方法详解

《Go路由注册方法详解》Go语言中,http.NewServeMux()和http.HandleFunc()是两种不同的路由注册方式,前者创建独立的ServeMux实例,适合模块化和分层路由,灵活性高... 目录Go路由注册方法1. 路由注册的方式2. 路由器的独立性3. 灵活性4. 启动服务器的方式5.

Go语言中三种容器类型的数据结构详解

《Go语言中三种容器类型的数据结构详解》在Go语言中,有三种主要的容器类型用于存储和操作集合数据:本文主要介绍三者的使用与区别,感兴趣的小伙伴可以跟随小编一起学习一下... 目录基本概念1. 数组(Array)2. 切片(Slice)3. 映射(Map)对比总结注意事项基本概念在 Go 语言中,有三种主要

Go Mongox轻松实现MongoDB的时间字段自动填充

《GoMongox轻松实现MongoDB的时间字段自动填充》这篇文章主要为大家详细介绍了Go语言如何使用mongox库,在插入和更新数据时自动填充时间字段,从而提升开发效率并减少重复代码,需要的可以... 目录前言时间字段填充规则Mongox 的安装使用 Mongox 进行插入操作使用 Mongox 进行更

SpringBoot中的404错误:原因、影响及解决策略

《SpringBoot中的404错误:原因、影响及解决策略》本文详细介绍了SpringBoot中404错误的出现原因、影响以及处理策略,404错误常见于URL路径错误、控制器配置问题、静态资源配置错误... 目录Spring Boot中的404错误:原因、影响及处理策略404错误的出现原因1. URL路径错

Go语言利用泛型封装常见的Map操作

《Go语言利用泛型封装常见的Map操作》Go语言在1.18版本中引入了泛型,这是Go语言发展的一个重要里程碑,它极大地增强了语言的表达能力和灵活性,本文将通过泛型实现封装常见的Map操作,感... 目录什么是泛型泛型解决了什么问题Go泛型基于泛型的常见Map操作代码合集总结什么是泛型泛型是一种编程范式,允

基于Go语言实现一个压测工具

《基于Go语言实现一个压测工具》这篇文章主要为大家详细介绍了基于Go语言实现一个简单的压测工具,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录整体架构通用数据处理模块Http请求响应数据处理Curl参数解析处理客户端模块Http客户端处理Grpc客户端处理Websocket客户端

Go中sync.Once源码的深度讲解

《Go中sync.Once源码的深度讲解》sync.Once是Go语言标准库中的一个同步原语,用于确保某个操作只执行一次,本文将从源码出发为大家详细介绍一下sync.Once的具体使用,x希望对大家有... 目录概念简单示例源码解读总结概念sync.Once是Go语言标准库中的一个同步原语,用于确保某个操