employee, err := getInformation(1000)
if err != nil {
// Something is wrong. Do something.
}
package main
import (
"fmt"
"os"
)
type Employee struct {
ID int
FirstName string
LastName string
Address string
}
func main() {
employee, err := getInformation(1001)
if err != nil {
// Something is wrong. Do something.
} else {
fmt.Print(employee)
}
}
func getInformation(id int) (*Employee, error) {
employee, err := apiCallEmployee(1000)
return employee, err
}
func apiCallEmployee(id int) (*Employee, error) {
employee := Employee{LastName: "Doe", FirstName: "John"}
return &employee, nil
}
错误处理策略
func getInformation(id int) (*Employee, error) {
employee, err := apiCallEmployee(1000)
if err != nil {
return nil, err // Simply return the error to the caller.
}
return employee, nil
}
你可能还需要在传播错误之前添加更多信息。 为此,可以使用fmt.Errorf() 函数,该函数与我们之前看到的函数类似,但它返回一个错误。 例如,你可以向错误添加更多上下文,但仍返回原始错误,如下所示:
func getInformation(id int) (*Employee, error) {
employee, err := apiCallEmployee(1000)
if err != nil {
return nil, fmt.Errorf("Got an error when getting the employee information: %v", err)
}
return employee, nil
}
另一种策略是在错误为暂时性错误时运行重试逻辑。 例如,可以使用重试策略调用函数三次并等待两秒钟,如下所示:
func getInformation(id int) (*Employee, error) {
for tries := 0; tries < 3; tries++ {
employee, err := apiCallEmployee(1000)
if err == nil {
return employee, nil
}
fmt.Println("Server is not responding, retrying ...")
time.Sleep(time.Second * 2)
}
return nil, fmt.Errorf("server has failed to respond to get the employee information")
}
创建可重用的错误
var ErrNotFound = errors.New("Employee not found!")
func getInformation(id int) (*Employee, error) {
if id != 1001 {
return nil, ErrNotFound
}
employee := Employee{LastName: "Doe", FirstName: "John"}
return &employee, nil
}
employee, err := getInformation(1000)
if errors.Is(err, ErrNotFound) {
fmt.Printf("NOT FOUND: %v\n", err)
} else {
fmt.Print(employee)
}
用于错误处理的推荐做法
- 始终检查是否存在错误,即使预期不存在。 然后正确处理它们,以免向最终用户公开不必要的信息。
- 在错误消息中包含一个前缀,以便了解错误的来源。 例如,可以包含包和函数的名称。
- 创建尽可能多的可重用错误变量。
- 了解使用返回错误和panic之间的差异。 不能执行其他操作时再使用panic。 例如,如果某个依赖项未准备就绪,则程序运行无意义(除非你想要运行默认行为)。
- 在记录错误时记录尽可能多的详细信息(我们将在下一部分介绍记录方法),并打印出最终用户能够理解的错误。
在Go中,可以使用net/http包来处理HTTP错误,该包为处理HTTP错误提供了内置支持。下面是一个示例代码片段,演示了如何在Go中处理HTTP错误:
package main
import (
"fmt"
"net/http"
)
func main() {
// send a GET request
resp, err := http.Get("http://example.com")
if err != nil {
// handle error
fmt.Println("Error sending request:", err)
return
}
defer resp.Body.Close()
// check for errors in the response status code
if resp.StatusCode != http.StatusOK {
// handle error
fmt.Println("Error: unexpected status code:", resp.StatusCode)
return
}
// process the response
// ...
}
在此代码片段中,我们使用http.Get函数向http://example.com发送GET请求。如果在请求过程中发生错误,我们会处理它并退出程序。如果响应状态码不是http.StatusOK(即200),我们处理错误并退出程序。否则,我们会根据需要处理响应。 您还可以使用http.Response.StatusCode字段和http.Response.Body字段。
下面是演示此方法的示例代码片段:
package main
import (
"fmt"
"io/ioutil"
"net/http"
)
func main() {
// send a GET request
resp, err := http.Get("http://example.com")
if err != nil {
// handle error
fmt.Println("Error sending request:", err)
return
}
defer resp.Body.Close()
// read the response body
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
// handle error
fmt.Println("Error reading response body:", err)
return
}
// check for errors in the response
if resp.StatusCode != http.StatusOK {
// handle error
fmt.Println("Error:", resp.StatusCode, string(body))
return
}
// process the response
// ...
}
在此代码片段中,我们使用http.Get函数向http://example.com发送GET请求。如果在请求期间或读取响应正文时发生错误,我们会处理它并退出程序。然后,我们检查响应状态代码和响应正文是否存在错误。如果发生错误,我们会处理它并退出程序。否则,我们会根据需要处理响应。
Route::group(function () {
Route::get('/list', [\App\Http\Controllers\Controller::class, 'list']);
});
group下只有一个路由会有如上报错。
如果你认为添加的sshkey,remote地址都正确,试一下清楚缓存。
git config --system --unset credential.helper
然后重新试一下。
我发现了在docker容器中安装snapd的问题:目前不支持以这种方式运行snapd。
这个问题已经在snapcraft论坛上被问到了。snapd的依赖项之一是systemd,如果不重新启动或重新登录,snapd服务就无法正确初始化。根据所有发行版的文档,这是必需的程序,但显然在docker中不是一个选项。
在docker主机上安装snapd,在运行时将snapd套接字装入已安装snapd的容器中。
这里是官方回复:无法在 docker 映像(ubuntu:19.10)中安装 snapcraft snap) - snapcraft - snapcraft.io
这是因为 node.js V17版本中最近发布的OpenSSL3.0, 而OpenSSL3.0对允许算法和密钥大小增加了严格的限制,可能会对生态系统造成一些影响。故此以前的项目在升级 nodejs 版本后会报错。
修改package.json,在相关构建命令之前加入SET NODE_OPTIONS=--openssl-legacy-provider,然后正常运行npm run serve即可。
"scripts": {
"serve": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve",
"build": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service build"
},
这是ImageMagic中有权限配置文件,需要修改PDF相关的读写权限。
# 打开policy.xml文件
sudo nano /etc/ImageMagick-6/policy.xml
# 修改PDF相关权限,由none改为read|write
<policy domain="coder" rights="none" pattern="PDF" />
# 改为
<policy domain="coder" rights="read|write" pattern="PDF" />