try_catch

package module
v0.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 24, 2022 License: MIT Imports: 1 Imported by: 0

README

Try-Catch的Go实现

一、这是什么?为什么会有这个?

在其他语言中有try-catch的实现,但是在Go里面并没有提供try-catch的实现,更蛋疼的是Go里面很多操作又很容易panic,对panic的捕获很麻烦,粒度不好区分,因此就想着能不能引入一个库解决一部分这种问题。

当然这种方式并不是一个好的最佳实践,只是我们需要让业务能够正常跑起来更健壮以免隔三差五背锅,仅此而已!

最后,切记:错误应该被尽早的暴露出来,而不是一味的掩盖!

二、安装

go get -u github.com/golang-infrastructure/go-try-catch

三、Try-Catch方法

提供了两种helper方法,一种是比较轻量级的方法,比如当有一段代码需要执行,但是不确定会不会产生错误,就可以这个样子:

package main

import (
	"errors"
	try_catch "github.com/golang-infrastructure/go-try-catch"
	"github.com/stretchr/testify/assert"
	"testing"
)

func TestTryCatch(t *testing.T) {

	var errFoo = errors.New("foo")

	// 正常执行
	err := try_catch.TryCatch(func() {
		t.Log("ok")
	})
	assert.Nil(t, err)

	// 执行时发生panic
	err = try_catch.TryCatch(func() {
		panic(errFoo)
	})
	assert.NotNil(t, err)
	assert.ErrorIs(t, err, errFoo)
}

如果需要返回值的话:

func TestTryCatchReturn(t *testing.T) {

	var errFoo = errors.New("foo")

	// 正常执行
	v, err := try_catch.TryCatchReturn(func() int {
		return 10086
	})
	assert.Nil(t, err)
	assert.Equal(t, 10086, v)

	// 执行时发生panic
	v, err = try_catch.TryCatchReturn(func() int {
		panic(errFoo)
	})
	assert.NotNil(t, err)
	assert.ErrorIs(t, err, errFoo)
}

如果需要更多返回值:

func TryCatchReturn2[R1, R2 any](f func() (R1, R2)) (r1 R1, r2 R2, err error) 
func TryCatchReturn3[R1, R2, R3 any](f func() (R1, R2, R3)) (r1 R1, r2 R2, r3 R3, err error) 

四、Try-Catch方法链

try-catch方法链就是定义了一些节点表示异常处理流程中的不同阶段,然后每个节点绑定对应的动作向下一阶段转移,整个状态图大概是这个样子的,其中节点是Struct,边是方法:

graphviz

Example:

package example

import (
	"errors"
	"fmt"
	try_catch "github.com/golang-infrastructure/go-try-catch"
	"testing"
)

func Test(t *testing.T) {

	// 正常执行
	try_catch.Try(func() {
		fmt.Println("ok")
	}).Do()

	// try发生异常,走catch
	var errFoo = errors.New("")
	try_catch.Try(func() {
		panic(errFoo)
	}).Catch(errors.New("bar"), func(err error) {
		fmt.Println("bar")
	}).Catch(errFoo, func(err error) {
		fmt.Println("foo")
	}).Do()

	// try发生异常,走默认catch
	try_catch.Try(func() {
		panic(errors.New("test"))
	}).Catch(errors.New("bar"), func(err error) {
		fmt.Println("bar")
	}).Catch(errFoo, func(err error) {
		fmt.Println("foo")
	}).DefaultCatch(func(err error) {
		fmt.Println("other")
	}).Do()

	// try未发生异常走else
	try_catch.Try(func() {
		_ = 100 + 19
	}).DefaultCatch(func(err error) {
		fmt.Println("other")
	}).Else(func() {
		fmt.Println("else")
	}).Do()

	// try发生异常,并且走finally
	try_catch.Try(func() {
		panic(errors.New("test"))
	}).DefaultCatch(func(err error) {
		fmt.Println("other")
	}).Else(func() {
		fmt.Println("else")
	}).Finally(func() {
		fmt.Println("finally")
	}).Do()

	// try未发生异常,并且走finally
	try_catch.Try(func() {
		_ = 100 + 19
	}).DefaultCatch(func(err error) {
		fmt.Println("other")
	}).Finally(func() {
		fmt.Println("finally")
	}).Do()

	// 发生panic,尝试捕获错误,但是没有捕获得到,则异常会被向上抛出,即仍然会panic
	try_catch.Try(func() {
		panic(errors.New("test"))
	}).Catch(errFoo, func(err error) {
		fmt.Println("catch success")
	}).Finally(func() {
		fmt.Println("not catch finally")
	}).Do()

}

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func TryCatch

func TryCatch(f func()) (err error)

TryCatch 带捕获错误的执行函数

func TryCatchReturn

func TryCatchReturn[R any](f func() R) (result R, err error)

TryCatchReturn 带捕获错误的执行返回结果的函数

func TryCatchReturn2

func TryCatchReturn2[R1, R2 any](f func() (R1, R2)) (r1 R1, r2 R2, err error)

func TryCatchReturn3

func TryCatchReturn3[R1, R2, R3 any](f func() (R1, R2, R3)) (r1 R1, r2 R2, r3 R3, err error)

Types

type CatchHandler

type CatchHandler struct {
	// contains filtered or unexported fields
}

CatchHandler 错误匹配

func NewCatchHandler

func NewCatchHandler(bindingTryHandler *TryHandler, err error, handler func(err error)) *CatchHandler

func (*CatchHandler) Catch

func (x *CatchHandler) Catch(err error, handler func(err error)) *CatchHandler

func (*CatchHandler) DefaultCatch

func (x *CatchHandler) DefaultCatch(handler func(err error)) *DefaultCatchHandler

func (*CatchHandler) Do

func (x *CatchHandler) Do()

func (*CatchHandler) Else

func (x *CatchHandler) Else(handler func()) *TryCatchElseHandler

func (*CatchHandler) Finally

func (x *CatchHandler) Finally(handler func()) *FinallyHandler

type DefaultCatchHandler

type DefaultCatchHandler struct {
	// contains filtered or unexported fields
}

DefaultCatchHandler 默认的TryCatch分支

func NewDefaultCatchHandler

func NewDefaultCatchHandler(bindingTryHandler *TryHandler, handler func(err error)) *DefaultCatchHandler

func (*DefaultCatchHandler) Do

func (x *DefaultCatchHandler) Do()

func (*DefaultCatchHandler) Else

func (x *DefaultCatchHandler) Else(handler func()) *TryCatchElseHandler

func (*DefaultCatchHandler) Finally

func (x *DefaultCatchHandler) Finally(handler func()) *FinallyHandler

type FinallyHandler

type FinallyHandler struct {
	// contains filtered or unexported fields
}

FinallyHandler 始终会执行

func NewFinallyHandler

func NewFinallyHandler(bindingTryHandler *TryHandler, handler func()) *FinallyHandler

func (*FinallyHandler) Do

func (x *FinallyHandler) Do()

type TryCatchElseHandler

type TryCatchElseHandler struct {
	// contains filtered or unexported fields
}

TryCatchElseHandler 在try执行块未发生错误时执行

func NewTryCatchElseHandler

func NewTryCatchElseHandler(bindingTryHandler *TryHandler, handler func()) *TryCatchElseHandler

func (*TryCatchElseHandler) Do

func (x *TryCatchElseHandler) Do()

func (*TryCatchElseHandler) Finally

func (x *TryCatchElseHandler) Finally(handler func()) *FinallyHandler

type TryHandler

type TryHandler struct {
	// contains filtered or unexported fields
}

TryHandler try块执行

func Try

func Try(funcToTry func()) *TryHandler

Try 创建一个TryHandler,可以看做是它的一个构造方法

func (*TryHandler) Catch

func (x *TryHandler) Catch(err error, handler func(err error)) *CatchHandler

func (*TryHandler) DefaultCatch

func (x *TryHandler) DefaultCatch(handler func(err error)) *DefaultCatchHandler

func (*TryHandler) Do

func (x *TryHandler) Do()

Do 开始执行整个流程

func (*TryHandler) Else

func (x *TryHandler) Else(handler func()) *TryCatchElseHandler

func (*TryHandler) Finally

func (x *TryHandler) Finally(handler func()) *FinallyHandler

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL