trycatch

package module
v0.0.1 Latest Latest
Warning

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

Go to latest
Published: Apr 28, 2021 License: GPL-3.0 Imports: 2 Imported by: 0

README

go try catch功能支持

功能说明

golang trycatch组件提供try...catch...finally功能, 改善go语言的错误处理流程

版本变更说明

  • v0.0.1

    完成功能开发与测试, 可以在生产环境使用.

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type CatchFunc

type CatchFunc func(context.Context, error) (ctx context.Context, caught bool)

CatchFunc 是catch阶段要求的功能封装类型, 在CatchFunc的具体实现中, 应该在函数的最开始处判断try阶段产生的错误是否是当前catch函数应该处理的, 如果是则处理并返回true, 否则应该返回false

type Context

type Context struct {
	context.Context
	// Data 是kv存储对象的实例; 如果用户想要使用自己的kv存储, 则建议将该字段初始化为指向kv存储对象的指针, 否则有可能无法在try...catch...finally的多个阶段共享同一份kv存储
	Data MapStore
}

Context 实现了ContextStore接口, 并支持KV存储

func (Context) Delete

func (c Context) Delete(key interface{})

Delete deletes the value for a key.

func (Context) Load

func (c Context) Load(key interface{}) (value interface{}, ok bool)

Load returns the value stored in the map for a key, or nil if no value is present. The ok result indicates whether value was found in the map.

func (Context) LoadAndDelete

func (c Context) LoadAndDelete(key interface{}) (value interface{}, loaded bool)

LoadAndDelete deletes the value for a key, returning the previous value if any. The loaded result reports whether the key was present.

func (Context) LoadOrStore

func (c Context) LoadOrStore(key interface{}, value interface{}) (actual interface{}, loaded bool)

LoadOrStore returns the existing value for the key if present. Otherwise, it stores and returns the given value. The loaded result is true if the value was loaded, false if stored.

func (Context) Range

func (c Context) Range(f func(key interface{}, value interface{}) bool)

Range calls f sequentially for each key and value present in the map. If f returns false, range stops the iteration.

Range does not necessarily correspond to any consistent snapshot of the Map's contents: no key will be visited more than once, but if the value for any key is stored or deleted concurrently, Range may reflect any mapping for that key from any point during the Range call.

Range may be O(N) with the number of elements in the map even if f returns false after a constant number of calls.

func (Context) Store

func (c Context) Store(key interface{}, value interface{})

Store sets the value for a key.

type ContextStore

type ContextStore interface {
	context.Context
	MapStore
}

ContextStore 组合了 context.Context接口 和 MapStore接口, 实现了对 带KV存储的上下文 的抽象

type Finally

type Finally func(context.Context) context.Context

Finally 是finally阶段要求的功能封装类型

type MapStore

type MapStore interface {
	Load(key interface{}) (value interface{}, ok bool)
	Store(key interface{}, value interface{})
	LoadAndDelete(key interface{}) (value interface{}, loaded bool)
	LoadOrStore(key interface{}, value interface{}) (actual interface{}, loaded bool)
	Delete(key interface{})
	Range(f func(key interface{}, value interface{}) bool)
}

MapStore 约束kv存储的实现方法

type TryCatch

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

TryCatch 的具体实现

func Try

func Try(f TryFunc) *TryCatch

Try 开始配置try...catch...finally流程

Example
// ctx 可以被try...catch...finally各阶段获取并修改
// caught 表明try阶段发生的err是否被其中一个catch函数正确处理, 如果try阶段没有发生任何异常, 那么没有任何catch函数会被执行, 该返回值也将为false
// err 是try阶段发生的异常

ctx, caught, err := Try(func(ctx context.Context) (context.Context, error) {
	// 上线文对象中可以存储kv数据
	if ictx, ok := ctx.(ContextStore); ok {
		ictx.Store("try", "ok")
	}

	// 模拟try解读的异常
	if ctx.Value("color").(string) == "red" || ctx.Value("color").(string) == "yellow" {
		return ctx, errors.New(ctx.Value("color").(string))
	}

	return ctx, nil
}).Catch(func(ctx context.Context, err error) (octx context.Context, caught bool) {
	// 在实际使用场景中, 这个地方应该对err进行类型断言, 如果满足断言条件则继续向下执行错误处理并返回true(后续的catch函数将不再执行嗯), 否则应该立即返回false表明当前catch无法处理该类型的错误
	if ctx.Value("color").(string) != "red" {
		return ctx, false
	}

	if ictx, ok := ctx.(ContextStore); ok {
		ictx.Store("catch1", "yes, red")
	}

	return ctx, true
}).Catch(func(ctx context.Context, err error) (octx context.Context, caught bool) {
	// 在实际使用场景中, 这个地方应该对err进行类型断言, 如果满足断言条件则继续向下执行错误处理并返回true(后续的catch函数将不再执行嗯), 否则应该立即返回false表明当前catch无法处理该类型的错误
	if ctx.Value("color").(string) != "yellow" {
		return ctx, false
	}

	if ictx, ok := ctx.(ContextStore); ok {
		ictx.Store("catch2", "yes, yellow")
	}

	return ctx, true
}).Catch(func(ctx context.Context, err error) (octx context.Context, caught bool) {
	// 在实际使用场景中, 这个地方应该对err进行类型断言, 如果满足断言条件则继续向下执行错误处理并返回true(后续的catch函数将不再执行嗯), 否则应该立即返回false表明当前catch无法处理该类型的错误
	if ctx.Value("color").(string) == "yellow" || ctx.Value("color").(string) == "red" {
		return ctx, false
	}

	if ictx, ok := ctx.(ContextStore); ok {
		ictx.Store("catch3", "yes, yellow")
	}
	return ctx, false
}).Finally(func(ctx context.Context) context.Context {
	if ictx, ok := ctx.(ContextStore); ok {
		ictx.Store("finally1", "yes")
	}
	return ctx
}).Finally(func(ctx context.Context) context.Context {
	if ictx, ok := ctx.(ContextStore); ok {
		ictx.Store("finally2", "yes")
	}
	return ctx
}).Run(context.WithValue(context.Background(), "color", "yellow"))

fmt.Printf("color=%s, caught=%v, err=%v\n", ctx.Value("color"), caught, err)
if ictx, ok := ctx.(ContextStore); ok {
	if v, ok := ictx.Load("try"); ok {
		fmt.Printf("try1=%s\n", v)
	}

	if v, ok := ictx.Load("catch1"); ok {
		fmt.Printf("catch1=%s\n", v)
	}

	if v, ok := ictx.Load("catch2"); ok {
		fmt.Printf("catch2=%s\n", v)
	}

	if v, ok := ictx.Load("catch3"); ok {
		fmt.Printf("catch3=%s\n", v)
	}

	if v, ok := ictx.Load("finally1"); ok {
		fmt.Printf("finally1=%s\n", v)
	}

	if v, ok := ictx.Load("finally2"); ok {
		fmt.Printf("finally2=%s\n", v)
	}
}

func (*TryCatch) Catch

func (t *TryCatch) Catch(f CatchFunc) *TryCatch

Catch 设置catch阶段的功能函数, 仅在Try阶段发生错误的时候才会按顺序执行catch函数

catch函数拿到try阶段的error后, 应该立即断言错误类型并判断自己能否处理该错误, 如果不能处理则应该返回false, 否则执行异常处理并在结束处理后返回true; 某一个catch返回true后后续的catch函数将不被执行, 并立即转到finally阶段执行

func (*TryCatch) Finally

func (t *TryCatch) Finally(f Finally) *TryCatch

Finally 无论是否发生错误, finally函数都将被执行; 可以设置多个finally函数, 它们将会按顺序执行

func (*TryCatch) Run

func (t *TryCatch) Run(ictx context.Context) (ctx context.Context, caught bool, err error)

Run 启动try...catch...finally流程

ictx 入参用于在try...catch...finally的各阶段传递信息; 本包Context结构体实现了ContextStore接口, 如果需要在context中存储kv数据, 则需要在try...catch...finally相应的处理函数中进行 ictx.(trycatch.ContextStore)断言

ctx 返回参数是ictx入参在try...catch...finally各阶段流转后最终的形态

caught 返回参数描述try阶段产生的error是否被某一catch阶段函数成功处理(即catch函数返回true), 如果try阶段没有发生错误则不会有任何catch函数被执行, 此时caught的值为false

err 返回参数是try阶段返回的原始错误信息

func (*TryCatch) Try

func (t *TryCatch) Try(f TryFunc) *TryCatch

Try 设置try阶段的功能函数, 只能设置一个try阶段的处理函数, 如果不设置try函数, 则Run尝试启动try...catch...finally的时候将会立即返回

type TryFunc

type TryFunc func(context.Context) (context.Context, error)

TryFunc 是try阶段要求的功能封装类型

Jump to

Keyboard shortcuts

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