Go并发模式之异常

出现异常表示着 系统 进入了 一个无法满足用户操作的状态,这个操作可能是显式的, 也可能是隐式的。 这是需要传达一些信息:
1。 发生了什么  : 对异常事件的描述
2。 发生在什么时间, 什么位置 :   异常还应该包含 栈轨信息;异常还应包含对应机器上时间,并最好utc 时间。
3。 对用户友好的信息 : 自定义信息;应该包括前两点的概述; 从用户角度考虑,给出信息
4。 告诉用户如何获得更多信息: 应该提供一个ID; 这个ID对应详细日志。

type MyError struct{
	Inner error
	Message string
	StackTrace string
	Misc map[string]interface{}
}

func wrapError(err error, messagef string, msgArgs ...interface{}) MyError{
	return MyError{
		Inner : err,
		Message : fmt.Sprintf(messagef, msgArgs...),
		StackTrace: string(debug.Stack()),
		Misc : make(map[string]interface{}),
	}
}

func (err MyError) Error() string{
	return err.Message
}

// lowLevel 模块
type LowLevelErr struct{
	error
}

func isGloballyExec(path string)(bool, error){
	info ,err := os.Stat(path)
	if err !=nil{
		return false, LowLevelErr{(wrapError(err, err.Error()))}
	}
	return info.Mode().Perm() &0100 == 0100, nil
}

// intermediate 模块
type IntermediateErr struct{
	error
}


func runJob(id string) error{
	const jobBinPath = "/bad/job/binary"
	isExecutable, err := isGloballyExec(jobBinPath)

	if err != nil{
		return err
	} else if isExecutable == false{
		return wrapError(nil, "job binary is not executable")
	}
	return exec.Command(jobBinPath, "--id="+id).Run()

}


func handleError(key int, err error, message string){
	log.SetPrefix(fmt.Sprintf("[logID:%v]:", key))
	log.Printf("%#v", err)
	fmt.Printf("[%v] %v", key, message)
}

func main() {
	log.SetOutput(os.Stdout)
	log.SetFlags(log.Ltime | log.LUTC)
	err := runJob("1")
	if err != nil{
		msg := "There was an unexpected issue; please report this as a bug."
		if _, ok := err.(IntermediateErr); ok{
			msg = err.Error()
		}
		handleError(1, err, msg)
	}
}
//[logID:1]:10:01:39 main.LowLevelErr{error:main.MyError{Inner:(*os.PathError)(0xc00006e180), Message:"stat /bad/job/binary: no such file or directory", StackTrace:"goroutine 1 [running]:\nruntime/debug.Stack(0xc000016180, 0x2f, 0x0)\n\t/usr/local/go/src/runtime/debug/stack.go:24 +0xa7\nmain.wrapError(0x10ed9e0, 0xc00006e180, 0xc000016180, 0x2f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)\n\t/Users/zhaozhiliang/Documents/work_www/go/src/concurrency/5/exception.go:22 +0xb4\nmain.isGloballyExec(0x10d89cb, 0xf, 0x8, 0x3, 0xc00001e070)\n\t/Users/zhaozhiliang/Documents/work_www/go/src/concurrency/5/exception.go:39 +0xbb\nmain.runJob(0x10d736a, 0x1, 0x22, 0x0)\n\t/Users/zhaozhiliang/Documents/work_www/go/src/concurrency/5/exception.go:51 +0x48\nmain.main()\n\t/Users/zhaozhiliang/Documents/work_www/go/src/concurrency/5/exception.go:71 +0x63\n", Misc:map[string]interface {}{}}}
//[1] There was an unexpected issue; please report this as a bug.

中间模块包装来自lowlevel 模块的异常

func runJob(id string) error{
	const jobBinPath = "/bad/job/binary"
	isExecutable, err := isGloballyExec(jobBinPath)
	if err != nil{
		return IntermediateErr{wrapError(err,
			"cannot run job %q: requisite binaries not available",
			id,
			)}
	} else if isExecutable == false{
		return wrapError(nil,
			"cannot run job %q: requisite binaries are not executable",
			id,)
	}

	return exec.Command(jobBinPath, "--id="+id).Run()
}

//[logID:1]:10:13:34 main.IntermediateErr{error:main.MyError{Inner:main.LowLevelErr{error:main.MyError{Inner:(*os.PathError)(0xc00006e180), Message:"stat /bad/job/binary: no such file or directory", StackTrace:"goroutine 1 [running]:\nruntime/debug.Stack(0xc000016180, 0x2f, 0x0)\n\t/usr/local/go/src/runtime/debug/stack.go:24 +0xa7\nmain.wrapError(0x10edc40, 0xc00006e180, 0xc000016180, 0x2f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)\n\t/Users/zhaozhiliang/Documents/work_www/go/src/concurrency/5/exception.go:22 +0xb4\nmain.isGloballyExec(0x10d8bab, 0xf, 0x1309300, 0x0, 0x203000)\n\t/Users/zhaozhiliang/Documents/work_www/go/src/concurrency/5/exception.go:39 +0xbb\nmain.runJob(0x10d754a, 0x1, 0x22, 0x0)\n\t/Users/zhaozhiliang/Documents/work_www/go/src/concurrency/5/exception.go:87 +0x4b\nmain.main()\n\t/Users/zhaozhiliang/Documents/work_www/go/src/concurrency/5/exception.go:73 +0x63\n", Misc:map[string]interface {}{}}}, Message:"cannot run job \"1\": requisite binaries not available", StackTrace:"goroutine 1 [running]:\nruntime/debug.Stack(0x10ddf7f, 0x33, 0xc000076e80)\n\t/usr/local/go/src/runtime/debug/stack.go:24 +0xa7\nmain.wrapError(0x10edce0, 0xc00000e240, 0x10ddf7f, 0x33, 0xc000076e80, 0x1, 0x1, 0x0, 0x0, 0x0, ...)\n\t/Users/zhaozhiliang/Documents/work_www/go/src/concurrency/5/exception.go:22 +0xb4\nmain.runJob(0x10d754a, 0x1, 0x22, 0x0)\n\t/Users/zhaozhiliang/Documents/work_www/go/src/concurrency/5/exception.go:89 +0x318\nmain.main()\n\t/Users/zhaozhiliang/Documents/work_www/go/src/concurrency/5/exception.go:73 +0x63\n", Misc:map[string]interface {}{}}}
//[1] cannot run job "1": requisite binaries not available

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值