try.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. package try
  2. import (
  3. "fmt"
  4. "reflect"
  5. "runtime/debug"
  6. )
  7. type TryCatch struct {
  8. TryFn interface{}
  9. TryParams []interface{}
  10. CatchFn interface{}
  11. CatchParams []interface{}
  12. }
  13. type TryInterface interface {
  14. Run()
  15. SetFn(interface{})
  16. SetCatchFn(fn interface{})
  17. SetTryParams(params []interface{})
  18. SetCatchParams(params []interface{})
  19. }
  20. func (t *TryCatch) SetFn(fn interface{}) {
  21. t.TryFn = fn
  22. }
  23. func (t *TryCatch) SetCatchFn(fn interface{}) {
  24. t.CatchFn = fn
  25. }
  26. func (t *TryCatch) SetTryParams(params []interface{}) {
  27. t.TryParams = params
  28. }
  29. func (t *TryCatch) SetCatchParams(params []interface{}) {
  30. t.CatchParams = params
  31. }
  32. func catchFunc(err interface{}) {
  33. fmt.Println(fmt.Sprintf("panic : %s\n", err))
  34. fmt.Println(fmt.Sprint(string(debug.Stack())))
  35. }
  36. func (t *TryCatch) getParams(params []interface{}) []reflect.Value {
  37. realParams := make([]reflect.Value, len(params))
  38. for i, param := range params {
  39. realParams[i] = reflect.ValueOf(param)
  40. }
  41. return realParams
  42. }
  43. func (t *TryCatch) Run() {
  44. go func() {
  45. defer func() {
  46. if err := recover(); err != nil {
  47. defer func() {
  48. if err = recover(); err != nil {
  49. catchFunc(err)
  50. }
  51. }()
  52. if t.CatchFn != nil {
  53. realCatchFunc := reflect.ValueOf(t.CatchFn)
  54. errParams := []reflect.Value{}
  55. errParams = append(errParams, reflect.ValueOf(err))
  56. for _, param := range t.CatchParams {
  57. errParams = append(errParams, reflect.ValueOf(param))
  58. }
  59. realCatchFunc.Call(errParams)
  60. } else {
  61. catchFunc(err)
  62. }
  63. }
  64. }()
  65. realFunc := reflect.ValueOf(t.TryFn)
  66. realFunc.Call(t.getParams(t.TryParams))
  67. }()
  68. }
  69. func Go(tryFunc func(), catchFunc func(interface{})) {
  70. go func(tryFunc func(), catchFunc func(interface{})) {
  71. defer func() {
  72. if err := recover(); err != nil {
  73. catchFunc(err)
  74. }
  75. }()
  76. tryFunc()
  77. }(tryFunc, catchFunc)
  78. }
  79. /**
  80. * tryFunc go func
  81. * catchFunc catch func
  82. * tryFunc params
  83. */
  84. func GoParams(tryFunc interface{}, catchFunc func(interface{}), fnParams ...interface{}) {
  85. realFunc := reflect.ValueOf(tryFunc)
  86. realParams := make([]reflect.Value, len(fnParams))
  87. for i, param := range fnParams {
  88. realParams[i] = reflect.ValueOf(param)
  89. }
  90. go func(realFunc reflect.Value, catchFunc func(interface{}), realParams []reflect.Value) {
  91. defer func() {
  92. if err := recover(); err != nil {
  93. catchFunc(err)
  94. }
  95. }()
  96. realFunc.Call(realParams)
  97. }(realFunc, catchFunc, realParams)
  98. }