рдРрд╕рд╛ рдЕрд╕рд╛рдзрд╛рд░рдг рдЬрд╛рдирд╛

рдЧреЛ 2 рдореЗрдВ рдирдИ рддреНрд░реБрдЯрд┐ рд╕реЗ рдирд┐рдкрдЯрдиреЗ рдХреЗ рдбрд┐рдЬрд╛рдЗрди рдХреЗ рдбреНрд░рд╛рдлреНрдЯ рд╣рд╛рд▓ рд╣реА рдореЗрдВ рдкреНрд░рдХрд╛рд╢рд┐рдд рд╣реБрдП рд╣реИрдВред рдпрд╣ рдмрд╣реБрдд рд╣реА рдордирднрд╛рд╡рди рд╣реИ рдХрд┐ рднрд╛рд╖рд╛ рдПрдХ рдЬрдЧрд╣ рдирд╣реАрдВ рдЦрдбрд╝реА рд╣реЛрддреА рд╣реИ - рдпрд╣ рд╡рд┐рдХрд╕рд┐рдд рд╣реЛрддреА рд╣реИ рдФрд░ рд╣рд░ рд╕рд╛рд▓ рдкреНрд░реЗрдЯрд┐рдпрд░ рдмрдврд╝рддреА рд╣реИред


рдХреЗрд╡рд▓ рдЕрдм, рдЬрдмрдХрд┐ рдЧреЛ 2 рдХреЗрд╡рд▓ рдХреНрд╖рд┐рддрд┐рдЬ рдкрд░ рджрд┐рдЦрд╛рдИ рджреЗрддрд╛ рд╣реИ, рдЗрдВрддрдЬрд╛рд░ рдХрд░рдирд╛ рдмрд╣реБрдд рджрд░реНрджрдирд╛рдХ рдФрд░ рджреБрдЦрдж рд╣реИред рдЗрд╕рд▓рд┐рдП, рд╣рдо рдорд╛рдорд▓реЛрдВ рдХреЛ рдЕрдкрдиреЗ рд╣рд╛рдереЛрдВ рдореЗрдВ рд▓реЗрддреЗ рд╣реИрдВред рдХреЛрдб рдкреАрдврд╝реА рдХрд╛ рдПрдХ рдЫреЛрдЯрд╛ рд╕рд╛, рдЦрдЧреЛрд▓ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд╛ рдПрдХ рдЫреЛрдЯрд╛ рд╕рд╛, рдФрд░ рд╣рд╛рде рдХреА рдереЛрдбрд╝реА рд╕реА рднреА рдЧрддрд┐ рдХреЗ рд╕рд╛рде рдкреИрдирд┐рдХ рдХреА рдмрд╛рд░реА, рдкреИрдирд┐рдХ рдХреА рдмрд╛рд░реА ... рд╕реБрд░реБрдЪрд┐рдкреВрд░реНрдг рдЕрдкрд╡рд╛рджреЛрдВ рдореЗрдВ!



рдФрд░ рддреБрд░рдВрдд рдореИрдВ рдПрдХ рдмрд╣реБрдд рдорд╣рддреНрд╡рдкреВрд░реНрдг рдФрд░ рдмрд┐рд▓реНрдХреБрд▓ рдЧрдВрднреАрд░ рдмрдпрд╛рди рджреЗрдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред
рдпрд╣ рдирд┐рд░реНрдгрдп рдкреНрд░рдХреГрддрд┐ рдореЗрдВ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдордиреЛрд░рдВрдЬрдХ рдФрд░ рд╢реИрдХреНрд╖рдгрд┐рдХ рд╣реИред
рдореЗрд░рд╛ рдорддрд▓рдм рд╕рд┐рд░реНрдл 4 рдордЬрд╝реЗ рд╕реЗ рд╣реИред рдпрд╣ рдЖрдо рддреМрд░ рдкрд░ рд╕рдЪреНрдЪрд╛рдИ рдореЗрдВ рдПрдХ рд╕рдмреВрдд рдХреА рдЕрд╡рдзрд╛рд░рдгрд╛ рд╣реИред рдореИрдВрдиреЗ рдЪреЗрддрд╛рд╡рдиреА рджреА :)

рддреЛ рдХреНрдпрд╛ рд╣реБрдЖ


рдкрд░рд┐рдгрд╛рдо рдПрдХ рдЫреЛрдЯрд╛ рд╕рд╛ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЛрдб рдЬрдирд░реЗрдЯрд░ рдерд╛ ред рдФрд░ рдХреЛрдб рдЬрдирд░реЗрдЯрд░, рдЬреИрд╕рд╛ рдХрд┐ рд╕рднреА рдЬрд╛рдирддреЗ рд╣реИрдВ, рдЕрдкрдиреЗ рдЖрдк рдореЗрдВ рдЕрдЪреНрдЫрд╛рдИ рдФрд░ рдЕрдиреБрдЧреНрд░рд╣ рд▓реЗ рдЬрд╛рддреЗ рд╣реИрдВред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдирд╣реАрдВ, рд▓реЗрдХрд┐рди рдЧреЛ рджреБрдирд┐рдпрд╛ рдореЗрдВ рд╡реЗ рдмрд╣реБрдд рд▓реЛрдХрдкреНрд░рд┐рдп рд╣реИрдВред


рд╣рдордиреЗ рдРрд╕реЗ рдХреЛрдб рдЬрдирд░реЗрдЯрд░ рдХреЛ рдЧреЛ-рд░реЙ рдкрд░ рд╕реЗрдЯ рдХрд┐рдпрд╛ рд╣реИред рд╡рд╣ рдорд╛рдирдХ go/ast рдореЙрдбреНрдпреВрд▓ рдХреА рдорджрдж рд╕реЗ рдЗрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИ, рдХреБрдЫ рдХрд░рддрд╛ рд╣реИ рдирд╣реАрдВ рдЪрд╛рд▓рд╛рдХ рд░реВрдкрд╛рдВрддрд░рдг, рдкрд░рд┐рдгрд╛рдо рдлрд╝рд╛рдЗрд▓ рдХреЗ рдЖрдЧреЗ рд▓рд┐рдЦрд╛ рд╣реИ, рдкреНрд░рддреНрдпрдп рдЬреЛрдбрд╝рдХрд░ _jex.go ред рдкрд░рд┐рдгрд╛рдореА рдлрд╝рд╛рдЗрд▓реЗрдВ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЫреЛрдЯреЗ рдХреНрд░рдо рдЪрд╛рд╣рддреЗ рд╣реИрдВред


рдЗрд╕ рд╕рд░рд▓ рддрд░реАрдХреЗ рд╕реЗ, рд╣рдо рдЕрдкрд╡рд╛рджреЛрдВ рдХреЛ рдЧреЛ рдореЗрдВ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВред


рд╣рдо рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ


рд╣рдо рдЬрдирд░реЗрдЯрд░ рдХреЛ рдлрд╝рд╛рдЗрд▓ рд╕реЗ рдХрдиреЗрдХреНрдЯ рдХрд░рддреЗ рд╣реИрдВ, рд╣реЗрдбрд░ рдореЗрдВ ( package рд╕реЗ рдкрд╣рд▓реЗ) рд╣рдо рд▓рд┐рдЦрддреЗ рд╣реИрдВ


 //+build jex //go:generate jex 

рдпрджрд┐ рдЖрдк рдЕрдм рдХрдорд╛рдВрдб go generate -tags jex рдЪрд▓рд╛рддреЗ go generate -tags jex , рддреЛ jex рдпреВрдЯрд┐рд▓рд┐рдЯреА рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХреА рдЬрд╛рдПрдЧреАред рд╡рд╣ os.Getenv("GOFILE") рд╕реЗ рдлрд╝рд╛рдЗрд▓ рдХрд╛ рдирд╛рдо рд▓реЗрддрд╛ рд╣реИ, рдЗрд╕реЗ рдЦрд╛рддрд╛ рд╣реИ, рдЗрд╕реЗ рдкрдЪрд╛рддрд╛ рд╣реИ рдФрд░ {file}_jex.go рд▓рд┐рдЦрддрд╛ рд╣реИред рд╣реЗрдбрд░ рдореЗрдВ рдирд╡рдЬрд╛рдд рдлрд╝рд╛рдЗрд▓ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА //+build !jex рд╣реИрдбрд░ рдореЗрдВ (рдЯреИрдЧ рдЙрд▓реНрдЯрд╛ рд╣реИ), рдЗрд╕рд▓рд┐рдП go build , рдФрд░ рдЗрд╕рдХреЗ рд╕рд╛рде рдХрдореНрдкрд╛рд░реНрдЯрдореЗрдВрдЯ рдореЗрдВ рдЕрдиреНрдп рдХрдорд╛рдВрдб, рдЬреИрд╕реЗ go test рдпрд╛ go install , рдХреЗрд╡рд▓ рдирдИ , рд╕рд╣реА рдлрд╛рдЗрд▓реЛрдВ рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦреЗрдВред рд▓реЗрдкреЛрдЯрд╛ ...


рдЕрдм рдбреЙрдЯ-рдЖрдпрд╛рдд github.com/anjensan/jex ред
рд╣рд╛рдБ, рдЬрдмрдХрд┐ рдПрдХ рдмрд┐рдВрджреБ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЖрдпрд╛рдд рдЕрдирд┐рд╡рд╛рд░реНрдп рд╣реИред рднрд╡рд┐рд╖реНрдп рдореЗрдВ рдЗрд╕реЗ рдЙрд╕реА рддрд░рд╣ рдЫреЛрдбрд╝рдиреЗ рдХреА рдпреЛрдЬрдирд╛ рд╣реИред


 import . "github.com/anjensan/jex" 

рдорд╣рд╛рди, рдЕрдм рдЖрдк рдХреЛрдб рдореЗрдВ THROW рдХрд╛рд░реНрдпреЛрдВ TRY , THROW , EX рдХреЙрд▓ рд╕рдореНрдорд┐рд▓рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЗрд╕ рд╕рдм рдХреЗ рд▓рд┐рдП, рдХреЛрдб рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рд░реВрдк рд╕реЗ рдорд╛рдиреНрдп рд╣реИ, рдФрд░ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдПрдХ рдЕрд╕рдВрд╕рд╛рдзрд┐рдд рд░реВрдк рдореЗрдВ рднреА рд╕рдВрдХрд▓рди рдХрд░рддрд╛ рд╣реИ (рдпрд╣ рд╕рд┐рд░реНрдл рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ), рдЗрд╕рд▓рд┐рдП рдСрдЯреЛ-рдкреВрд░реНрдгрддрд╛ рдЙрдкрд▓рдмреНрдз рд╣реИ рдФрд░ рд▓рд┐рдВрдЯрд░ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХрд╕рдо рдирд╣реАрдВ рдЦрд╛рддреЗ рд╣реИрдВред рд╕рдВрдкрд╛рджрдХреЛрдВ рдХреЛ рдЗрди рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдкреНрд░рд▓реЗрдЦрди рднреА рджрд┐рдЦрд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдЕрдЧрд░ рдХреЗрд╡рд▓ рдЙрдирдХреЗ рдкрд╛рд╕ рдПрдХ рдерд╛ред


рдПрдХ рдЕрдкрд╡рд╛рдж рдлреЗрдВрдХ рджреЗрдВ


 THROW(errors.New("error name")) 

рдЕрдкрд╡рд╛рдж рдХреЛ рдкрдХрдбрд╝реЛ


 if TRY() { //   } else { fmt.Println(EX()) } 

рдПрдХ рдЕрдирд╛рдо рдлрд╝рдВрдХреНрд╢рди рд╣реБрдб рдХреЗ рддрд╣рдд рдЙрддреНрдкрдиреНрди рд╣реЛрддрд╛ рд╣реИред рдФрд░ рдЗрд╕рдореЗрдВ defer ред рдФрд░ рдЗрд╕рдХрд╛ рдПрдХ рдФрд░ рдХрд╛рд░реНрдп рд╣реИред рдФрд░ рдЗрд╕реЗ recover ... рдЦреИрд░, рдЕрднреА рднреА return рдФрд░ defer рд╕реЗ рдирд┐рдкрдЯрдиреЗ рдХреЗ рд▓рд┐рдП рдереЛрдбрд╝рд╛ рд╕рд╛ рдЬрд╛рджреВ-рдЯреЛрдирд╛ рд╣реИред


рдФрд░ рд╣рд╛рдБ, рд╡реИрд╕реЗ, рд╡реЗ рд╕рдорд░реНрдерд┐рдд рд╣реИрдВ!


рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдПрдХ рд╡рд┐рд╢реЗрд╖ рдореИрдХреНрд░реЛ рдЪрд░ ERR ред рдпрджрд┐ рдЖрдк рдЗрд╕рдореЗрдВ рдХреЛрдИ рддреНрд░реБрдЯрд┐ рджреЗрддреЗ рд╣реИрдВ, рддреЛ рдПрдХ рдЕрдкрд╡рд╛рдж рдлреЗрдВрдХ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдРрд╕реЗ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдХреЙрд▓ рдХрд░рдирд╛ рдЖрд╕рд╛рди рд╣реИ рдЬреЛ рдЕрднреА рднреА рдкреБрд░рд╛рдиреЗ рддрд░реАрдХреЗ рд╕реЗ рдПрдХ error рд▓реМрдЯрд╛рддреЗ рд╣реИрдВ


 file, ERR := os.Open(filename) 

рдЗрд╕рдХреЗ рдЕрддрд┐рд░рд┐рдХреНрдд, рд╡рд╣рд╛рдБ рдЫреЛрдЯреЗ рдЙрдкрдпреЛрдЧрд┐рддрд╛ рдмреИрдЧ рдХреЗ рдПрдХ рдЬреЛрдбрд╝реЗ рд╣реИрдВ ex рдФрд░ must , рд▓реЗрдХрд┐рди рд╡рд╣рд╛рдБ рдмрд╣реБрдд рдХреБрдЫ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдирд╣реАрдВ рд╣реИред


рдЙрджрд╛рд╣рд░рдг


рдпрд╣рд╛рдБ рд╕рд╣реА, рдореБрд╣рд╛рд╡рд░реЗрджрд╛рд░ рдЧреЛ рдХреЛрдб рдХрд╛ рдЙрджрд╛рд╣рд░рдг рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ


 func CopyFile(src, dst string) error { r, err := os.Open(src) if err != nil { return fmt.Errorf("copy %s %s: %v", src, dst, err) } defer r.Close() w, err := os.Create(dst) if err != nil { return fmt.Errorf("copy %s %s: %v", src, dst, err) } if _, err := io.Copy(w, r); err != nil { w.Close() os.Remove(dst) return fmt.Errorf("copy %s %s: %v", src, dst, err) } if err := w.Close(); err != nil { os.Remove(dst) return fmt.Errorf("copy %s %s: %v", src, dst, err) } } 

рдпрд╣ рдХреЛрдб рдЗрддрдирд╛ рдЕрдЪреНрдЫрд╛ рдФрд░ рд╕реБрд░реБрдЪрд┐рдкреВрд░реНрдг рдирд╣реАрдВ рд╣реИред рд╡реИрд╕реЗ, рдпрд╣ рдХреЗрд╡рд▓ рдореЗрд░реА рд░рд╛рдп рдирд╣реАрдВ рд╣реИ!
рд▓реЗрдХрд┐рди jex рд╣рдореЗрдВ рдЗрд╕реЗ рдмреЗрд╣рддрд░ рдмрдирд╛рдиреЗ рдореЗрдВ рдорджрдж рдХрд░реЗрдЧреАред


 func CopyFile_(src, dst string) { defer ex.Logf("copy %s %s", src, dst) r, ERR := os.Open(src) defer r.Close() w, ERR := os.Create(dst) if TRY() { ERR := io.Copy(w, r) ERR := w.Close() } else { w.Close() os.Remove(dst) THROW() } } 

рд▓реЗрдХрд┐рди рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХрд╛рд░реНрдпрдХреНрд░рдо


 func main() { hex, err := ioutil.ReadAll(os.Stdin) if err != nil { log.Fatal(err) } data, err := parseHexdump(string(hex)) if err != nil { log.Fatal(err) } os.Stdout.Write(data) } 

рдХреЗ рд░реВрдк рдореЗрдВ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ


 func main() { if TRY() { hex, ERR := ioutil.ReadAll(os.Stdin) data, ERR := parseHexdump(string(hex)) os.Stdout.Write(data) } else { log.Fatal(EX()) } } 

рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рд╡рд┐рдЪрд╛рд░ рдХреЛ рдмреЗрд╣рддрд░ рдорд╣рд╕реВрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдпрд╣рд╛рдВ рдПрдХ рдФрд░ рдЙрджрд╛рд╣рд░рдг рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдореВрд▓ рдХреЛрдб


 func printSum(a, b string) error { x, err := strconv.Atoi(a) if err != nil { return err } y, err := strconv.Atoi(b) if err != nil { return err } fmt.Println("result:", x + y) return nil } 

рдХреЗ рд░реВрдк рдореЗрдВ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ


 func printSum_(a, b string) { x, ERR := strconv.Atoi(a) y, ERR := strconv.Atoi(b) fmt.Println("result:", x + y) } 

рдпрд╛ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐


 func printSum_(a, b string) { fmt.Println("result:", must.Int_(strconv.Atoi(a)) + must.Int_(strconv.Atoi(b))) } 

рдЕрдкрд╡рд╛рдж


рдиреАрдЪреЗ рдХреА рд░реЗрдЦрд╛ error рдЙрджрд╛рд╣рд░рдг рдкрд░ рдПрдХ рд╕рд░рд▓ рдЖрд╡рд░рдг рд╕рдВрд░рдЪрдирд╛ рд╣реИред


 type exception struct { //  ,   err error //  ^W , ,    log []interface{} //      ,    suppress []*exception } 

рдПрдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд┐рдВрджреБ рдпрд╣ рд╣реИ рдХрд┐ рд╕рд╛рдзрд╛рд░рдг рдЖрддрдВрдХ рд╣рдорд▓реЛрдВ рдХреЛ рдЕрдкрд╡рд╛рдж рдХреЗ рд░реВрдк рдореЗрдВ рдирд╣реАрдВ рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП, runtime.TypeAssertionError рдЬреИрд╕реА рд╕рднреА рдорд╛рдирдХ рддреНрд░реБрдЯрд┐рдпрд╛рдБ рдХреЛрдИ рдЕрдкрд╡рд╛рдж рдирд╣реАрдВ рд╣реИрдВред рдпрд╣ рдЧреЛ рдореЗрдВ рд╕реНрд╡реАрдХреГрдд рд╕рд░реНрд╡реЛрддреНрддрдо рдкреНрд░рдерд╛рдУрдВ рдХреЗ рдЕрдиреБрд░реВрдк рд╣реИ - рдЕрдЧрд░ рд╣рдорд╛рд░реЗ рдкрд╛рд╕, рдирд┐рд▓-рдбреЗрд░реЗрдлреЗрд░реЗрдВрд╕ рд╣реИ, рддреЛ рд╣рдо рдкреВрд░реА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рд╣рд░реНрд╖ рдФрд░ рдЦреБрд╢реА рд╕реЗ рдЫреЛрдбрд╝ рджреЗрддреЗ рд╣реИрдВред рд╡рд┐рд╢реНрд╡рд╕рдиреАрдп рдФрд░ рдЕрдиреБрдорд╛рдирд┐рддред рд╣рд╛рд▓рд╛рдБрдХрд┐ рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ, рд╢рд╛рдпрдж рдпрд╣ рдЗрд╕ рдкрд▓ рдХреА рд╕рдореАрдХреНрд╖рд╛ рдХрд░рдиреЗ рдФрд░ рдРрд╕реА рдЧрд▓рддрд┐рдпреЛрдВ рдХреЛ рдкрдХрдбрд╝рдиреЗ рдХреЗ рд▓рд╛рдпрдХ рд╣реИред рд╢рд╛рдпрдж рд╡реИрдХрд▓реНрдкрд┐рдХ?


рдФрд░ рдпрд╣рд╛рдБ рдПрдХ рдЕрдкрд╡рд╛рдж рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╣реИ


 func one_() { THROW(errors.New("one")) } func two_() { THROW(errors.New("two") } func three() { if TRY() { one_() } else { two_() } } 

рдпрд╣рд╛рдВ рд╣рдо рд╢рд╛рдВрддрд┐ рд╕реЗ рдЕрдкрд╡рд╛рдж рдХреЛ рд╕рдВрднрд╛рд▓рддреЗ рд╣реИрдВ, рдЬреИрд╕реЗ рдХрд┐ рдЕрдЪрд╛рдирдХ рдмреИрдо ... рдФрд░ рдЕрдкрд╡рд╛рдж two рдлреЗрдВрдХ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рддреЛ, рд╕реНрд░реЛрдд one suppress рд╕реЗ рдЗрд╕реЗ suppress рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рд╕рдВрд▓рдЧреНрди one ред рдХреБрдЫ рднреА рдирд╣реАрдВ рдЦреЛ рдЬрд╛рдПрдЧрд╛, рд╕рдм рдХреБрдЫ рд▓реЙрдЧ рдореЗрдВ рдЬрд╛рдПрдЧрд╛ред рдЗрд╕рд▓рд┐рдП, рдмрд╣реБрдд рд▓реЛрдХрдкреНрд░рд┐рдп fmt.Errorf("blabla: %v", err) рдкреИрдЯрд░реНрди fmt.Errorf("blabla: %v", err) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕реАрдзреЗ рд╕рдВрджреЗрд╢ рдкрд╛рда рдореЗрдВ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреА рдкреВрд░реА рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХреЛ рдзрдХреЗрд▓рдиреЗ рдХреА рдХреЛрдИ рд╡рд┐рд╢реЗрд╖ рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдХреЛрдИ рднреА, рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдпрд╣рд╛рдВ рдЗрд╕рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЛ рдкреНрд░рддрд┐рдмрдВрдзрд┐рдд рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдпрджрд┐ рдЖрдк рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЪрд╛рд╣рддреЗ рд╣реИрдВред


рдЬрдм рдкрдХрдбрд╝рдирд╛ рднреВрд▓ рдЧрдпрд╛


рдЖрд╣, рдПрдХ рдФрд░ рдмрд╣реБрдд рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд┐рдВрджреБред рдкрдардиреАрдпрддрд╛ рдмрдврд╝рд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рдЬрд╛рдВрдЪ рд╣реИ: рдпрджрд┐ рдХреЛрдИ рдлрд╝рдВрдХреНрд╢рди рдЕрдкрд╡рд╛рдж рдХреЛ рдлреЗрдВрдХ рд╕рдХрддрд╛ рд╣реИ, рддреЛ рдЙрд╕рдХрд╛ рдирд╛рдо _ рд╕рд╛рде рд╕рдорд╛рдкреНрдд рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдПрдХ рдЬрд╛рдирдмреВрдЭрдХрд░ рдЯреЗрдврд╝рд╛ рдирд╛рдо рдЬреЛ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рдХреЛ рдмрддрд╛рдПрдЧрд╛ "рдкреНрд░рд┐рдп рдорд╣реЛрджрдп, рдпрд╣рд╛рдВ рдЖрдкрдХреЗ рдХрд╛рд░реНрдпрдХреНрд░рдо рдореЗрдВ рдХреБрдЫ рдЧрд▓рдд рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдХреГрдкрдпрд╛ рд╕рд╛рд╡рдзрд╛рди рдФрд░ рдореЗрд╣рдирддреА рд░рд╣реЗрдВ!"


рдПрдХ рдЬрд╛рдБрдЪ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рд░реВрдкрд╛рдВрддрд░рд┐рдд рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рд▓рд┐рдП рд╢реБрд░реВ рд╣реЛрддреА рд╣реИ, рд╕рд╛рде рд╣реА рдЗрд╕реЗ jex-check рдХрдорд╛рдВрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдореЗрдВ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рд╢реБрд░реВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рд╢рд╛рдпрдж рдЕрдиреНрдп рдмрд┐рд▓реНрдбрд░реЛрдВ рдХреЗ рд╕рд╛рде рдирд┐рд░реНрдорд╛рдг рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рд╣рд┐рд╕реНрд╕реЗ рдХреЗ рд░реВрдк рдореЗрдВ рдЗрд╕реЗ рдЪрд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИред


рдЯрд┐рдкреНрдкрдгреА рдЬрд╛рдБрдЪ //jex:nocheck ред рдпрд╣, рд╡реИрд╕реЗ, рдПрдХ рдЕрдирд╛рдо рдлрд╝рдВрдХреНрд╢рди рд╕реЗ рдЕрдкрд╡рд╛рджреЛрдВ рдХреЛ рдлреЗрдВрдХрдиреЗ рдХрд╛ рдПрдХрдорд╛рддреНрд░ рддрд░реАрдХрд╛ рд╣реИред


рдмреЗрд╢рдХ, рдпрд╣ рд╕рднреА рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЗ рд▓рд┐рдП рд░рд╛рдордмрд╛рдг рдирд╣реАрдВ рд╣реИред рдЪреЗрдХрд░ рдЗрд╕рд╕реЗ рдЪреВрдХ рдЬрд╛рдПрдЧрд╛


 func bad_() { THROW(errors.New("ups")) } func worse() { f := bad_ f() } 

рджреВрд╕рд░реА рдУрд░, рдпрд╣ рдЧрд▓рдд err declared and not used рд▓рд┐рдП рдорд╛рдирдХ рдЬрд╛рдВрдЪ рд╕реЗ рдмрд╣реБрдд рдЦрд░рд╛рдм err declared and not used , рдЬрд┐рд╕реЗ рджрд░рдХрд┐рдирд╛рд░ рдХрд░рдирд╛ рдмрд╣реБрдд рдЖрд╕рд╛рди рд╣реИред


 func worse() { a, err := foo() if err != nil { return err } b, err := bar() //  ,    ok... go vet, ? } 

рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдпрд╣ рдкреНрд░рд╢реНрди рджрд╛рд░реНрд╢рдирд┐рдХ рд╣реИ, рдХреНрдпрд╛ рдХрд░рдирд╛ рдмреЗрд╣рддрд░ рд╣реИ рдЬрдм рдЖрдк рддреНрд░реБрдЯрд┐ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдирд╛ рднреВрд▓ рдЧрдП - рдЪреБрдкрдЪрд╛рдк рдЗрд╕реЗ рдЕрдирджреЗрдЦрд╛ рдХрд░реЗрдВ, рдпрд╛ рдПрдХ рдЖрддрдВрдХ рдмрд╛рд╣рд░ рдлреЗрдВрдХ рджреЗрдВ ... рд╡реИрд╕реЗ, рдкрд░реАрдХреНрд╖рдг рдХреЗ рд╕рд░реНрд╡реЛрддреНрддрдо рдкрд░рд┐рдгрд╛рдо рдХрдВрдкрд╛рдЗрд▓рд░ рдореЗрдВ рдЕрдкрд╡рд╛рдж рд╕рдорд░реНрдерди рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдХреЗ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдЗрд╕ рд▓реЗрдЦ рдХреЗ рджрд╛рдпрд░реЗ рд╕реЗ рдкрд░реЗ рд╣реИред ред


рдХреБрдЫ рд▓реЛрдЧ рдХрд╣ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпрд╣ рдПрдХ рдЕрджреНрднреБрдд рд╕рдорд╛рдзрд╛рди рд╣реИ, рдпрд╣ рдЕрдм рдПрдХ рдЕрдкрд╡рд╛рдж рдирд╣реАрдВ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЕрдм рдЕрдкрд╡рд╛рдж рдХрд╛ рдорддрд▓рдм рдмрд╣реБрдд рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реИред рдЦреИрд░, рд╡рд╣рд╛рдБ, рдХреНрдпреЛрдВрдХрд┐ рд╕реНрдЯреИрдХ рдХреЗ рдирд┐рд╢рд╛рди рдЕрдкрд╡рд╛рджреЛрдВ рд╕реЗ рдЬреБрдбрд╝реЗ рдирд╣реАрдВ рд╣реИрдВ, рдпрд╛ рдлрд╝рдВрдХреНрд╢рди рдирд╛рдореЛрдВ рдХреА рдЬрд╛рдБрдЪ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрд▓рдЧ рд▓рд╛рдЗрдирд░ рд╣реИ, рдпрд╛ рдпрд╣ рдлрд╝рдВрдХреНрд╢рди _ рд╕рд╛рде рд╕рдорд╛рдкреНрдд рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЕрдкрд╡рд╛рджреЛрдВ рдХреЛ рдлреЗрдВрдХрдирд╛ рдирд╣реАрдВ рд╣реИ, рдпрд╛ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдореЗрдВ рдХреЛрдИ рдкреНрд░рддреНрдпрдХреНрд╖ рд╕рдорд░реНрдерди рдирд╣реАрдВ рд╣реИ, рдпрд╛ рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЖрддрдВрдХ рд╣реИ, рдФрд░ рдШрдмрд░рд╛рд╣рдЯ рдПрдХ рдЕрдкрд╡рд╛рдж рдирд╣реАрдВ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд╣реИрдкреНрдкреАрдпреЛрд▓рд╕ ... рдмреАрдЬрд╛рдгреБ рдмреЗрдХрд╛рд░ рдФрд░ рд╡реНрдпрд░реНрде рдХреЗ рд░реВрдк рдореЗрдВ рдЧрд░реНрдо рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП, рдореИрдВ рдЙрдиреНрд╣реЗрдВ рд▓реЗрдЦ рдХреЗ рдмреЛрд░реНрдб рдХреЗ рдкреАрдЫреЗ рдЫреЛрдбрд╝ рджреВрдВрдЧрд╛, рдФрд░ рдореИрдВ рд╡рд░реНрдгрд┐рдд рд╕рдорд╛рдзрд╛рди рдХреЛ рдЕрдирдЬрд╛рдиреЗ рдореЗрдВ "рдЕрдкрд╡рд╛рдж" рдХрд╣реВрдВрдЧрд╛ред


рдвреЗрд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ


рдЕрдХреНрд╕рд░ рдбреЗрд╡рд▓рдкрд░реНрд╕, рдбрд┐рдмрдЧрд┐рдВрдЧ рдХреЛ рд╕рд░рд▓ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдХрд╕реНрдЯрдо error рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд▓рд┐рдП рдПрдХ рд╕реНрдЯреИрдХ рдЯреНрд░реЗрд╕ рдХреЛ рдЪрд┐рдкрдХрд╛рддреЗ рд╣реИрдВред рдЗрд╕рдХреЗ рд▓рд┐рдП рдХрдИ рд▓реЛрдХрдкреНрд░рд┐рдп рдкреБрд╕реНрддрдХрд╛рд▓рдп рднреА рд╣реИрдВред рд▓реЗрдХрд┐рди, рд╕реМрднрд╛рдЧреНрдп рд╕реЗ, рдЕрдкрд╡рд╛рджреЛрдВ рдХреЗ рд╕рд╛рде, рдЧреЛ рдХреА рдПрдХ рджрд┐рд▓рдЪрд╕реНрдк рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЗ рдХрд╛рд░рдг рдЗрд╕реЗ рдХрд┐рд╕реА рднреА рдЕрддрд┐рд░рд┐рдХреНрдд рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИ - рдЖрддрдВрдХ рдХреЗ рджреМрд░рд╛рди, рдХреЛрдб рдХреЗ рдвреЗрд░ рд╕рдВрджрд░реНрдн рдореЗрдВ defer рдмреНрд▓реЙрдХреЛрдВ defer рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬреЛ рдЖрддрдВрдХ рдХреЛ рдлреЗрдВрдХ рджреЗрддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП рдпрд╣рд╛рдБ


 func foo_() { THROW(errors.New("ups")) } func bar() { if TRY() { foo_() } else { debug.PrintStack() } } 

рдПрдХ рдкреВрд░реНрдг-рд╕реНрдЯреИрдХ рдЯреНрд░реЗрд╕ рдЯреНрд░реЗрд╕ рд╣реЛрдЧрд╛, рдереЛрдбрд╝реА рд╕реА рдХреНрд░рд┐рдпрд╛ (рдореИрдВ рдлрд╝рд╛рдЗрд▓ рдирд╛рдо рдХрд╛рдЯ рджреЗрддрд╛ рд╣реВрдВ)


  runtime/debug.Stack runtime/debug.PrintStack main.bar.func2 github.com/anjensan/jex/runtime.TryCatch.func1 panic main.foo_ main.bar.func1 github.com/anjensan/jex/runtime.TryCatch main.bar main.main 

рд╕реНрдЯреИрдХ рдЯреНрд░реЗрд╕ рдХреЛ рдлреЙрд░реНрдореЗрдЯ рдХрд░рдиреЗ / рдкреНрд░рд┐рдВрдЯ рдХрд░рдиреЗ, рд╕рд░реЛрдЧреЗрдЯ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрддреЗ рд╣реБрдП, рдЙрдиреНрд╣реЗрдВ рдкрдардиреАрдпрддрд╛ рдХреЗ рд▓рд┐рдП рдЫрд┐рдкрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рд╕рд╣рд╛рдпрдХ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЪреЛрдЯ рдирд╣реАрдВ рдкрд╣реБрдВрдЪрддреА рд╣реИред рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдПрдХ рдЕрдЪреНрдЫрд╛ рд╡рд┐рдЪрд╛рд░ рд╣реИ, рдореЗрдВ рд▓рд┐рдЦрд╛ рд╣реИред


рдпрд╛ рдЖрдк рд╕реНрдЯреИрдХ рдХреЛ рдкрдХрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ ex.Log() рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕реЗ рдЕрдкрд╡рд╛рдж рдореЗрдВ рд╕рдВрд▓рдЧреНрди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдлрд┐рд░, рдЗрд╕ рддрд░рд╣ рдХреЗ рдЕрдкрд╡рд╛рдж рдХреЛ рдХрд┐рд╕реА рдЕрдиреНрдп рд╣реЙрд░рд┐рди рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреА рдЬрд╛рддреА рд╣реИ - рд╕реНрдЯреНрд░реЗрдХреНрддреНрд░реЗрд╕ рдЦреЛ рдирд╣реАрдВ рдЬрд╛рддреЗ рд╣реИрдВред


 func foobar_() { e := make(chan error, 1) go func() { defer close(e) if TRY() { checkZero_() } else { EX().Log(debug.Stack()) //   e <- EX().Wrap() //     } }() ex.Must_(<-e) //  ,  ,  } 

рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ


рдПрд╣ ... рдмреЗрд╢рдХ, рдРрд╕рд╛ рдХреБрдЫ рдмреЗрд╣рддрд░ рд▓рдЧреЗрдЧрд╛


  try { throw io.EOF, "some comment" } catch e { fmt.Printf("exception: %v", e) } 

рд▓реЗрдХрд┐рди рдЕрдлрд╕реЛрд╕, рдЖрд╣, рдЧреЛ рдХреА рд╡рд╛рдХреНрдп рд░рдЪрдирд╛ рдЧреИрд░-рдПрдХреНрд╕реНрдЯреЗрдВрд╕рд┐рдмрд▓ рд╣реИред
[рд╡рд┐рдЪрд╛рд░рдкреВрд░реНрд╡рдХ] рд╣рд╛рд▓рд╛рдВрдХрд┐, рд╢рд╛рдпрдж, рдпрд╣ рдмреЗрд╣рддрд░ рдХреЗ рд▓рд┐рдП рд╣реИ ...


рдХрд┐рд╕реА рднреА рдорд╛рдорд▓реЗ рдореЗрдВ, рдЖрдкрдХреЛ рдмрд┐рдЧрд╛рдбрд╝рдирд╛ рд╣реЛрдЧрд╛ред рд╡реИрдХрд▓реНрдкрд┐рдХ рд╡рд┐рдЪрд╛рд░реЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдмрдирд╛рдирд╛ рдерд╛


  TRY; { THROW(io.EOF, "some comment") }; CATCH; { fmt.Printf("exception: %v", EX) } 

рд▓реЗрдХрд┐рди рдЗрд╕ рддрд░рд╣ рдХреЗ рдХреЛрдб go fmt рдмрд╛рдж рдЧреВрдВрдЧрд╛ рджрд┐рдЦрддрд╛ рд╣реИред рдФрд░ рдХрдВрдкрд╛рдЗрд▓рд░ рд╢рдкрде рд▓реЗрддрд╛ рд╣реИ рдЬрдм рд╡рд╣ рджреЛрдиреЛрдВ рд╢рд╛рдЦрд╛рдУрдВ рдореЗрдВ return рд╣реИред if-TRY рд╕рд╛рде рдРрд╕реА рдХреЛрдИ рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рд╣реИред


рдпрд╣ рдЬрд░реВрд░реА рд╣реЛрдЧрд╛ рдХрд┐ ERR рдореИрдХреНрд░реЛ рдХреЛ MUST рдлрдВрдХреНрд╢рди (рд╕рд┐рд░реНрдл рдЗрд╕рд╕реЗ рдмреЗрд╣рддрд░) рд╕реЗ рдмрджрд▓рд╛ рдЬрд╛рдПред рд▓рд┐рдЦрдиреЗ рдХреЗ рдХреНрд░рдо рдореЗрдВ


  return MUST(strconv.Atoi(a)) + MUST(strconv.Atoi(b)) 

рд╕рд┐рджреНрдзрд╛рдВрдд рд░реВрдк рдореЗрдВ, рдпрд╣ рдЕрднреА рднреА рд╕рдВрднрд╡ рд╣реИ, рдЬрдм рдПрд╕реНрдЯ рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рд╕рднреА рдкреНрд░рдХрд╛рд░ рдХреЗ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд╕рднреА рдкреНрд░рдХрд╛рд░ рдХреЗ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдЖрд╡рд░рдг рдлрд╝рдВрдХреНрд╢рди рдЙрддреНрдкрдиреНрди рд╣реЛрддрд╛ рд╣реИ, рдЬреИрд╕реЗ рдХрд┐ рдкреИрдХреЗрдЬ рдореЗрдВ рдШреЛрд╖рд┐рдд рдХрд┐рдП рдЧрдП, рдФрд░ рдлрд┐рд░ рд╕рдВрдмрдВрдзрд┐рдд рд╕рд░реЛрдЧреЗрдЯ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдирд╛рдо рдХреЗ рд╕рд╛рде MUST рдХреЛ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрд┐рдд MUST ред рдпрд╣ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рддреБрдЪреНрдЫ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕рдВрднрд╡ рд╣реИ ... рдХреЗрд╡рд▓ рд╕рдВрдкрд╛рджрдХ / рд╡рд┐рдЪрд╛рд░рдХ рдРрд╕реЗ рдХреЛрдб рдХреЛ рд╕рдордЭ рдирд╣реАрдВ рдкрд╛рдПрдВрдЧреЗред рдЖрдЦрд┐рд░рдХрд╛рд░, рдЧреЛрд╕реНрдЯ рд╕рд┐рд╕реНрдЯрдо рдХреЗ рднреАрддрд░ MUST рд╕реНрдЯрдм рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реИред рдФрд░ рдЗрд╕рд▓рд┐рдП рдХреЛрдИ рд╕реНрд╡рдд: рдкреВрд░реНрдг рдирд╣реАрдВ рд╣реИред


рд╣реБрдб рдХреЗ рдиреАрдЪреЗ


рд╕рднреА рд╕рдВрд╕рд╛рдзрд┐рдд рдлрд╝рд╛рдЗрд▓реЛрдВ рдореЗрдВ рдПрдХ рдирдпрд╛ рдЖрдпрд╛рдд рдЬреЛрдбрд╝рд╛ рдЬрд╛рддрд╛ рд╣реИред


  import _jex "github.com/anjensan/jex/runtime" 

panic(_jex.NewException(...)) рдХреЙрд▓ THROW panic(_jex.NewException(...)) THROW рдмрджрд▓ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред EX() рд╕реНрдерд╛рдиреАрдп рдЪрд░ рдХреЗ рдирд╛рдо рд╕реЗ рднреА рдмрджрд▓рд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдкрдХрдбрд╝рд╛ рдЧрдпрд╛ рдЕрдкрд╡рд╛рдж рд╣реЛрддрд╛ рд╣реИред


рд▓реЗрдХрд┐рди if TRY() {..} else {..} рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рддреЛ рдереЛрдбрд╝рд╛ рдФрд░ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рд╣реИред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╕рднреА return рдФрд░ defer рд▓рд┐рдП рд╡рд┐рд╢реЗрд╖ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рд╣реЛрддрд╛ рд╣реИред рддрдм рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЕрдЧрд░ рд╢рд╛рдЦрд╛рдУрдВ рдХреЛ рдЧреБрдордирд╛рдо рдХрд╛рд░реНрдпреЛрдВ рдореЗрдВ рд░рдЦрд╛ рдЬрд╛рддрд╛ рд╣реИред рдФрд░ рдлрд┐рд░ рдпреЗ рдлрд╝рдВрдХреНрд╢рди _jex.TryCatch(..) рдХреЛ рдкрд╛рд╕ рдХрд░ _jex.TryCatch(..) рдЬрд╛рддреЗ рд╣реИрдВред рдпрд╣рд╛рдБ рд╣реИ


 func test(a int) (int, string) { fmt.Println("before") if TRY() { if a == 0 { THROW(errors.New("a == 0")) } defer fmt.Printf("a = %d\n", a) return a + 1, "ok" } else { fmt.Println("fail") } return 0, "hmm" } 

рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдмрджрд▓ рдЬрд╛рддрд╛ рд╣реИ (рдореИрдВрдиреЗ //line рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдХреЛ рд╣рдЯрд╛ рджрд┐рдпрд╛):


 func test(a int) (_jex_r0 int, _jex_r1 string) { var _jex_ret bool fmt.Println("before") var _jex_md2502 _jex.MultiDefer defer _jex_md2502.Run() _jex.TryCatch(func() { if a == 0 { panic(_jex.NewException(errors.New("a == 0"))) } { _f, _p0, _p1 := fmt.Printf, "a = %d\n", a _jex_md2502.Defer(func() { _f(_p0, _p1) }) } _jex_ret, _jex_r0, _jex_r1 = true, a+1, "ok" return }, func(_jex_ex _jex.Exception) { defer _jex.Suppress(_jex_ex) fmt.Println("fail") }) if _jex_ret { return } return 0, "hmm" } 

рдПрдХ рдмрд╣реБрдд, рд╕реБрдВрджрд░ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рдареАрдХ рд╣реИ, рд╕рдм рдирд╣реАрдВ рдФрд░ рд╣рдореЗрд╢рд╛ рдирд╣реАрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЖрдк TRY рдХреЗ рдЕрдВрджрд░ defer-recover рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ, рдХреНрдпреЛрдВрдХрд┐ рдлрдВрдХреНрд╢рди рдХреЙрд▓ рдЕрддрд┐рд░рд┐рдХреНрдд рд▓реИрдореНрдмреНрдбрд╛ рдореЗрдВ рдмрджрд▓ рдЬрд╛рддрд╛ рд╣реИред


рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЬрдм рдЖрд╢реНрдЪрд░реНрдпрдЬрдирдХ рдкреЗрдбрд╝ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╡рд┐рдХрд▓реНрдк "рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдХреЛ рд╕рд╣реЗрдЬреЗрдВ" рдЗрдВрдЧрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рддреЛ, рд╕рд┐рджреНрдзрд╛рдВрдд рд░реВрдк рдореЗрдВ, go/printer рдХреЛ рдЙрдиреНрд╣реЗрдВ рдкреНрд░рд┐рдВрдЯ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП ... рд╡рд╣ рдЬреЛ рдИрдорд╛рдирджрд╛рд░реА рд╕реЗ рдХрд░рддрд╛ рд╣реИ, рд╕рдЪреНрдЪрд╛рдИ рдмрд╣реБрдд, рдмрд╣реБрдд рдХреБрдЯрд┐рд▓ рд╣реИ =) рдореИрдВ рдЙрджрд╛рд╣рд░рдг рдирд╣реАрдВ рджреВрдВрдЧрд╛, рдмрд╕ рдХреБрдЯрд┐рд▓ред рд╕рд┐рджреНрдзрд╛рдВрдд рд░реВрдк рдореЗрдВ, рдРрд╕реА рд╕рдорд╕реНрдпрд╛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╣рд▓ рдХрд░рдиреЗ рдпреЛрдЧреНрдп рд╣реИ рдпрджрд┐ рдЖрдк рд╕рд╛рд╡рдзрд╛рдиреАрдкреВрд░реНрд╡рдХ рд╕рднреА рдПрд╕реНрдЯреНрд░реЛ-рдиреЛрдбреНрд╕ (рдЕрдм рд╡реЗ рдЦрд╛рд▓реА рд╣реИрдВ) рдХреЗ рд▓рд┐рдП рдкрджреЛрдВ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдпрд╣ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдЪреАрдЬреЛрдВ рдХреА рд╕реВрдЪреА рдореЗрдВ рд╢рд╛рдорд┐рд▓ рдирд╣реАрдВ рд╣реИред


рдХреЛрд╢рд┐рд╢


рдЬрд┐рдЬреНрдЮрд╛рд╕рд╛ рд╕реЗ рдмрд╛рд╣рд░, рдореИрдВрдиреЗ рдПрдХ рдЫреЛрдЯрд╛ рдмреЗрдВрдЪрдорд╛рд░реНрдХ рд▓рд┐рдЦрд╛ред


рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рд▓рдХрдбрд╝реА рдХреЗ qsort рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реИ рдЬреЛ рд▓реЛрдб рдореЗрдВ рдбреБрдкреНрд▓рд┐рдХреЗрдЯ рдХреЗ рд▓рд┐рдП рдЬрд╛рдВрдЪ рдХрд░рддрд╛ рд╣реИред рдорд┐рд▓рд╛ - рдПрдХ рдЧрд▓рддреАред рдПрдХ рд╕рдВрд╕реНрдХрд░рдг рдмрд╕ рдЗрд╕реЗ return err fmt.Errorf рд╕реЗ рдлреЗрдВрдХрддрд╛ рд╣реИ, рджреВрд╕рд░рд╛ fmt.Errorf рдХрд╣рдХрд░ рддреНрд░реБрдЯрд┐ рдХреЛ рд╕реНрдкрд╖реНрдЯ рдХрд░рддрд╛ рд╣реИред рдФрд░ рдПрдХ рдФрд░ рдЕрдкрд╡рд╛рджреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рд╣рдо рд╡рд┐рднрд┐рдиреНрди рдЖрдХрд╛рд░реЛрдВ рдХреЗ рд╕реНрд▓рд╛рдЗрд╕реЛрдВ рдХреЛ рдЫрд╛рдВрдЯрддреЗ рд╣реИрдВ, рдпрд╛ рддреЛ рдмрд┐рдирд╛ рдбреБрдкреНрд▓рд┐рдХреЗрдЯ рдХреЗ (рдмрд┐рдирд╛ рдХрд┐рд╕реА рддреНрд░реБрдЯрд┐ рдХреЗ, рд╕реНрд▓рд╛рдЗрд╕ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕реЙрд░реНрдЯ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ), рдпрд╛ рдПрдХ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдХреЗ рд╕рд╛рде (рд▓рдЧрднрдЧ рдЖрдзреЗ рд░рд╛рд╕реНрддреЗ рд╕реЗ рдЫрдВрдЯрдиреА рд╣реЛрддреА рд╣реИ, рдЗрд╕реЗ рдЯрд╛рдЗрдорд┐рдВрдЧ рджреНрд╡рд╛рд░рд╛ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ)ред


рдкрд░рд┐рдгрд╛рдо
 ~ > cat /proc/cpuinfo | grep 'model name' | head -1 model name : Intel(R) Core(TM) i7-6700K CPU @ 4.00GHz ~ > go version go version go1.11 linux/amd64 ~ > go test -bench=. github.com/anjensan/jex/demo goos: linux goarch: amd64 pkg: github.com/anjensan/jex/demo BenchmarkNoErrors/_____10/exception-8 10000000 236 ns/op BenchmarkNoErrors/_____10/return_err-8 5000000 255 ns/op BenchmarkNoErrors/_____10/fmt.errorf-8 5000000 287 ns/op BenchmarkNoErrors/____100/exception-8 500000 3119 ns/op BenchmarkNoErrors/____100/return_err-8 500000 3194 ns/op BenchmarkNoErrors/____100/fmt.errorf-8 500000 3533 ns/op BenchmarkNoErrors/___1000/exception-8 30000 42356 ns/op BenchmarkNoErrors/___1000/return_err-8 30000 42204 ns/op BenchmarkNoErrors/___1000/fmt.errorf-8 30000 44465 ns/op BenchmarkNoErrors/__10000/exception-8 3000 525864 ns/op BenchmarkNoErrors/__10000/return_err-8 3000 524781 ns/op BenchmarkNoErrors/__10000/fmt.errorf-8 3000 561256 ns/op BenchmarkNoErrors/_100000/exception-8 200 6309181 ns/op BenchmarkNoErrors/_100000/return_err-8 200 6335135 ns/op BenchmarkNoErrors/_100000/fmt.errorf-8 200 6687197 ns/op BenchmarkNoErrors/1000000/exception-8 20 76274341 ns/op BenchmarkNoErrors/1000000/return_err-8 20 77806506 ns/op BenchmarkNoErrors/1000000/fmt.errorf-8 20 78019041 ns/op BenchmarkOneError/_____10/exception-8 2000000 712 ns/op BenchmarkOneError/_____10/return_err-8 5000000 268 ns/op BenchmarkOneError/_____10/fmt.errorf-8 2000000 799 ns/op BenchmarkOneError/____100/exception-8 500000 2296 ns/op BenchmarkOneError/____100/return_err-8 1000000 1809 ns/op BenchmarkOneError/____100/fmt.errorf-8 500000 3529 ns/op BenchmarkOneError/___1000/exception-8 100000 21168 ns/op BenchmarkOneError/___1000/return_err-8 100000 20747 ns/op BenchmarkOneError/___1000/fmt.errorf-8 50000 24560 ns/op BenchmarkOneError/__10000/exception-8 10000 242077 ns/op BenchmarkOneError/__10000/return_err-8 5000 242376 ns/op BenchmarkOneError/__10000/fmt.errorf-8 5000 251043 ns/op BenchmarkOneError/_100000/exception-8 500 2753692 ns/op BenchmarkOneError/_100000/return_err-8 500 2824116 ns/op BenchmarkOneError/_100000/fmt.errorf-8 500 2845701 ns/op BenchmarkOneError/1000000/exception-8 50 33452819 ns/op BenchmarkOneError/1000000/return_err-8 50 33374000 ns/op BenchmarkOneError/1000000/fmt.errorf-8 50 33705994 ns/op PASS ok github.com/anjensan/jex/demo 64.008s 

рдпрджрд┐ рддреНрд░реБрдЯрд┐ рдХреЛ рдлреЗрдВрдХ рдирд╣реАрдВ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ (рдХреЛрдб рд╕реНрдерд┐рд░ рдФрд░ рдкреНрд░рдмрд▓рд┐рдд рдХрдВрдХреНрд░реАрдЯ рд╣реИ), рддреЛ рдЕрдкрд╡рд╛рдж рдлреЗрдВрдХрдиреЗ рдХреА рдЧрд╛рд░рдВрдЯреА рд▓рдЧрднрдЧ fmt.Errorf рдФрд░ fmt.Errorf return err рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддреБрд▓рдиреАрдп рд╣реИред рдХрднреА-рдХрднреА рдереЛрдбрд╝рд╛ рддреЗрдЬред рд▓реЗрдХрд┐рди рдЕрдЧрд░ рддреНрд░реБрдЯрд┐ рдХреЛ рдлреЗрдВрдХ рджрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рддреЛ рдЕрдкрд╡рд╛рдж рджреВрд╕рд░реЗ рд╕реНрдерд╛рди рдкрд░ рдЬрд╛рддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рдпрд╣ рд╕рдм "рдЙрдкрдпреЛрдЧреА рдХрд╛рд░реНрдп / рддреНрд░реБрдЯрд┐" рдФрд░ рд╕реНрдЯреИрдХ рдХреА рдЧрд╣рд░рд╛рдИ рдХреЗ рдЕрдиреБрдкрд╛рдд рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИред рдЫреЛрдЯреЗ рд╕реНрд▓рд╛рдЗрд╕ рдХреЗ рд▓рд┐рдП, return err рдЧреИрдк рд╕реЗ рдЖрдЧреЗ рдЬрд╛рддрд╛ рд╣реИ, рдордзреНрдпрдо рдФрд░ рдмрдбрд╝реЗ рд╕реНрд▓рд╛рдЗрд╕ рдХреЗ рд▓рд┐рдП, рдЕрдкрд╡рд╛рдж рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдореИрдиреНрдпреБрдЕрд▓ рдлреЙрд░рд╡рд░реНрдбрд┐рдВрдЧ рдХреЗ рдмрд░рд╛рдмрд░ рд╣реИрдВред


рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ, рдпрджрд┐ рддреНрд░реБрдЯрд┐рдпрд╛рдВ рдЕрддреНрдпрдВрдд рджреБрд░реНрд▓рдн рд╣реИрдВ, рддреЛ рдЕрдкрд╡рд╛рдж рднреА рдХреЛрдб рдХреЛ рдереЛрдбрд╝рд╛ рдЧрддрд┐ рджреЗ рд╕рдХрддреЗ рд╣реИрдВред рдЕрдЧрд░ рд╣рд░ рдХрд┐рд╕реА рдХреЛ рдкрд╕рдВрдж рд╣реИ, рддреЛ рдпрд╣ рдХреБрдЫ рдРрд╕рд╛ рд╣реЛрдЧрд╛ред рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдмрд╣реБрдд рдмрд╛рд░ ... рддреЛ рдзреАрдореА рдЧрддрд┐ рд╕реЗ рдЕрдкрд╡рд╛рдж рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╕рдорд╕реНрдпрд╛ рд╕реЗ рджреВрд░ рд╣реИрдВ, рдЬрд┐рд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЪрд┐рдВрддрд╛ рдХрд░рдиреЗ рдпреЛрдЧреНрдп рд╣реИред


рдПрдХ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд░реВрдк рдореЗрдВ, рдореИрдВрдиреЗ рдЕрдкрд╡рд╛рджреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд╛рд╕реНрддрд╡рд┐рдХ gosh рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдорд╛рдЗрдЧреНрд░реЗрдЯ рдХрд┐рдпрд╛ ред


рдореЗрд░реЗ рдЧрд╣рд░реЗ рдЕрдлрд╝рд╕реЛрд╕ рдХреЗ рд▓рд┐рдП, рдЗрд╕рдиреЗ 1-рдЗрди -1 рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрдиреЗ рдХрд╛ рдХрд╛рдо рдирд╣реАрдВ рдХрд┐рдпрд╛

рдЕрдзрд┐рдХ рд╕рдЯреАрдХ рд░реВрдк рд╕реЗ, рдпрд╣ рдирд┐рдХрд▓рд╛ рд╣реЛрдЧрд╛, рд▓реЗрдХрд┐рди рдпрд╣ рдкрд░реЗрд╢рд╛рди рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред


рдЗрд╕рд▓рд┐рдП, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, rpc2XML рдлрд╝рдВрдХреНрд╢рди error рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд▓рдЧрддрд╛ рд╣реИ ... рд╣рд╛рдВ, рдпрд╣ рдХрднреА рднреА рдЗрд╕реЗ рд╡рд╛рдкрд╕ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рдпрджрд┐ рдЖрдк рдПрдХ рдЕрд╕рдорд░реНрдерд┐рдд рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░ рдХреЛ рдХреНрд░рдордмрджреНрдз рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВ - рдХреЛрдИ рддреНрд░реБрдЯрд┐ рдирд╣реАрдВ, рдмрд╕ рдЦрд╛рд▓реА рдЖрдЙрдЯрдкреБрдЯред рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдпрд╣реА рдЗрд░рд╛рджрд╛ рдерд╛? .. рдирд╣реАрдВ, рд╡рд┐рд╡реЗрдХ рдЙрд╕реЗ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдЫреЛрдбрд╝рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреЗрддрд╛ рд╣реИред рджреНрд╡рд╛рд░рд╛ рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛


  default: THROW(fmt.Errorf("unsupported type %T", value)) 

рд▓реЗрдХрд┐рди рдпрд╣ рдкрддрд╛ рдЪрд▓рд╛ рдХрд┐ рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдПрдХ рд╡рд┐рд╢реЗрд╖ рддрд░реАрдХреЗ рд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ


 func rpcParams2XML(rpc interface{}) (string, error) { var err error buffer := "<params>" for i := 0; i < reflect.ValueOf(rpc).Elem().NumField(); i++ { var xml string buffer += "<param>" xml, err = rpc2XML(reflect.ValueOf(rpc).Elem().Field(i).Interface()) buffer += xml buffer += "</param>" } buffer += "</params>" return buffer, err } 

рдпрд╣рд╛рдВ рд╣рдо рдорд╛рдкрджрдВрдбреЛрдВ рдХреА рд╕реВрдЪреА рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЪрд▓рддреЗ рд╣реИрдВ, рдЙрди рд╕рднреА рдХреЛ рдХреНрд░рдордмрджреНрдз рдХрд░рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдХреЗрд╡рд▓ рдмрд╛рдж рдХреЗ рд▓рд┐рдП рдПрдХ рддреНрд░реБрдЯрд┐ рд╡рд╛рдкрд╕ рдХрд░рддреЗ рд╣реИрдВред рд╢реЗрд╖ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдирдЬрд░рдЕрдВрджрд╛рдЬ рдХрд░ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЕрдЬреАрдм рд╡реНрдпрд╡рд╣рд╛рд░ рдЖрд╕рд╛рди рдмрдирд╛ рджрд┐рдпрд╛


 func rpcParams2XML_(rpc interface{}) string { buffer := "<params>" for i := 0; i < reflect.ValueOf(rpc).Elem().NumField(); i++ { buffer += "<param>" buffer += rpc2XML_(reflect.ValueOf(rpc).Elem().Field(i).Interface()) buffer += "</param>" } buffer += "</params>" return buffer } 

рдпрджрд┐ рдХрдо рд╕реЗ рдХрдо рдПрдХ рдХреНрд╖реЗрддреНрд░ рдХреЛ рдХреНрд░рдордмрджреНрдз рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╛рдо рдирд╣реАрдВ рдХрд┐рдпрд╛ - рдПрдХ рдЧрд▓рддреАред рдЦреИрд░, рдпрд╣ рдмреЗрд╣рддрд░ рд╣реИред рд▓реЗрдХрд┐рди рдпрд╣ рдкрддрд╛ рдЪрд▓рд╛ рдХрд┐ рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдПрдХ рд╡рд┐рд╢реЗрд╖ рддрд░реАрдХреЗ рд╕реЗ рднреА рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред


 xmlstr, _ = rpcResponse2XML(response) 

рдлрд┐рд░ рд╕реЗ, рд╕реНрд░реЛрдд рдХреЛрдб рдХреЗ рд▓рд┐рдП рдпрд╣ рдЗрддрдирд╛ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдирд╣реАрдВ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдЕрдирджреЗрдЦрд╛ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдореИрдВ рдпрд╣ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдирд╛ рд╢реБрд░реВ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ рдХрд┐ рдХреБрдЫ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рд╕реНрдкрд╖реНрдЯ рддреНрд░реБрдЯрд┐ рд╕реЗ рдирд┐рдкрдЯрдиреЗ рдХреЗ рд╢реМрдХреАрди рд╣реЛрддреЗ рд╣реИрдВ if err != nil рдорд╛рдзреНрдпрдо рд╕реЗ if err != nil ... рд▓реЗрдХрд┐рди рдЕрдкрд╡рд╛рджреЛрдВ рдХреЗ рд╕рд╛рде рдЗрд╕реЗ рдЕрднреА рднреА рдЕрдЧреНрд░реЗрд╖рд┐рдд рдХрд░рдирд╛ рдЖрд╕рд╛рди рд╣реИ рдпрд╛ рдЕрдирджреЗрдЦрд╛ рдХрд░рдирд╛ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╣реИред


 xmlstr = rpcResponse2XML_(response) 

рдФрд░ рдореИрдВрдиреЗ "рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреА рд╢реНрд░реГрдВрдЦрд▓рд╛" рдХреЛ рджреВрд░ рдХрд░рдирд╛ рд╢реБрд░реВ рдирд╣реАрдВ рдХрд┐рдпрд╛ред рдпрд╣рд╛рдБ рдореВрд▓ рдХреЛрдб рд╣реИ


 func DecodeClientResponse(r io.Reader, reply interface{}) error { rawxml, err := ioutil.ReadAll(r) if err != nil { return FaultSystemError } return xml2RPC(string(rawxml), reply) } 

рдпрд╣рд╛рдБ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рд╣реИ


 func DecodeClientResponse_(r io.Reader, reply interface{}) { var rawxml []byte if TRY() { rawxml, ERR = ioutil.ReadAll(r) } else { THROW(FaultSystemError) } xml2RPC_(string(rawxml), reply) } 

рдпрд╣рд╛рдВ рдореВрд▓ рддреНрд░реБрдЯрд┐ (рдЬреЛ ioutil.ReadAll рд▓реМрдЯреА рд╣реИ) рдЦреЛ рдирд╣реАрдВ рдЬрд╛рдПрдЧреА, рдЗрд╕реЗ suppress рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рдЕрдкрд╡рд╛рдж рд╕реЗ рдЬреЛрдбрд╝рд╛ рдЬрд╛рдПрдЧрд╛ред рдлрд┐рд░ рд╕реЗ, рдЗрд╕реЗ рдореВрд▓ рд░реВрдк рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕реЗ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рднреНрд░рдорд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП ...


рдореИрдВ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрддрд╛ рд╣реВрдВ, if err != nil { log.Error(..) } рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдЕрдкрд╡рд╛рдж рдлреЗрдВрдХ рдХреЗ рд╕рд╛рдеред рдПрдХ рдирдХрд╛рд░рд╛рддреНрдордХ рдмрд┐рдВрджреБ рд╣реИ - рдкрд░реАрдХреНрд╖рдг рдмрд╣реБрдд рдкрд╣рд▓реЗ рддреНрд░реБрдЯрд┐ рдкрд░ рдЖрддреЗ рд╣реИрдВ, рдХрд╛рдо рдХрд░рдирд╛ рдЬрд╛рд░реА рдирд╣реАрдВ рд░рдЦрддреЗ рд╣реИрдВ "рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ, рдХрдо рд╕реЗ рдХрдо рдХрд┐рд╕реА рднреА рддрд░рд╣"ред рдорди рдХреЗ рдЕрдиреБрд╕рд╛рд░, рдЙрдиреНрд╣реЗрдВ рдЙрдк-рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реЛрдЧрд╛ ... рдХреНрдпрд╛, рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдХрд┐рд╕реА рднреА рдорд╛рдорд▓реЗ рдореЗрдВ рдХрд░рдиреЗ рдпреЛрдЧреНрдп рд╣реИред рд▓реЗрдХрд┐рди рд╕рд╣реА рд╕реНрдЯреИрдХреНрд░реЗрд╕ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдмрд╣реБрдд рдЖрд╕рд╛рди рд╣реИ


 func errorReporter(t testing.TB) func(error) { return func(e error) { t.Log(string(debug.Stack())) t.Fatal(e) } } func TestRPC2XMLConverter_(t *testing.T) { defer ex.Catch(errorReporter(t)) // ... xml := rpcRequest2XML_("Some.Method", req) } 

рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдЕрдирджреЗрдЦрд╛ рдХрд░рдирд╛ рдмрд╣реБрдд рдЖрд╕рд╛рди рд╣реИред рдореВрд▓ рдХреЛрдб рдореЗрдВ


 func fault2XML(fault Fault) string { buffer := "<methodResponse><fault>" xml, _ := rpc2XML(fault) buffer += xml buffer += "</fault></methodResponse>" return buffer } 

рдпрд╣рд╛рдБ rpc2XML рд╕реЗ рддреНрд░реБрдЯрд┐ rpc2XML рдлрд┐рд░ рд╕реЗ рдЪреБрдкрдЪрд╛рдк рдЕрдирджреЗрдЦрд╛ рдХрд░ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдРрд╕рд╛ рд╣реЛ рдЧрдпрд╛ рд╣реИ


 func fault2XML(fault Fault) string { buffer := "<methodResponse><fault>" if TRY() { buffer += rpc2XML_(fault) } else { fmt.Printf("ERR: %v", EX()) buffer += "<nil/>" } buffer += "</fault></methodResponse>" return buffer } 

рдореЗрд░реА рд╡реНрдпрдХреНрддрд┐рдЧрдд рднрд╛рд╡рдирд╛рдУрдВ рдХреЗ рдЕрдиреБрд╕рд╛рд░, рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде "рдЕрд░реНрдз-рд╕рдорд╛рдкреНрдд" рдкрд░рд┐рдгрд╛рдо рд▓реМрдЯрдирд╛ рдЖрд╕рд╛рди рд╣реИред
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ рдЖрдзрд╛ рдирд┐рд░реНрдорд┐рдд рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ред рдЕрдкрд╡рд╛рдж рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рдлрд╝рдВрдХреНрд╢рди рдпрд╛ рддреЛ рдПрдХ рд╕рдлрд▓ рдкрд░рд┐рдгрд╛рдо рджреЗрддрд╛ рд╣реИ рдпрд╛ рдХреБрдЫ рднреА рдирд╣реАрдВ рджреЗрддрд╛ рд╣реИред рдПрдХ рдкреНрд░рдХрд╛рд░ рдХреА рдкрд░рдорд╛рдгреБред рджреВрд╕рд░реА рдУрд░, рдЕрдкрд╡рд╛рджреЛрдВ рдХреА рд╢реНрд░реГрдВрдЦрд▓рд╛ рдореЗрдВ рдореВрд▓ рдХрд╛рд░рдг рдХреЛ рдЕрдирджреЗрдЦрд╛ рдХрд░рдирд╛ рдпрд╛ рдЦреЛрдирд╛ рдЕрдзрд┐рдХ рдХрдард┐рди рд╣реИред рдЖрдЦрд┐рд░рдХрд╛рд░, рдЖрдкрдХреЛ рдЕрднреА рднреА рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдРрд╕рд╛ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рдиреА рд╣реЛрдЧреАред рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде, рдпрд╣ рдЖрд╕рд╛рдиреА рд╕реЗ рдФрд░ рд╕реНрд╡рд╛рднрд╛рд╡рд┐рдХ рд░реВрдк рд╕реЗ рд╣реЛрддрд╛ рд╣реИред


рдПрдХ рдирд┐рд╖реНрдХрд░реНрд╖ рдХреЗ рдмрдЬрд╛рдп


рдЗрд╕ рд▓реЗрдЦ рдХреЛ рд▓рд┐рдЦрддреЗ рд╕рдордп, рдХреЛрдИ рднреА рдЧреЛрдлрд░ рдШрд╛рдпрд▓ рдирд╣реАрдВ рд╣реБрдЖ рдерд╛ред


рдЧреЛрдлрд╝рд░-рд╢рд░рд╛рдмреА http://migranov.ru рдХреА рддрд╕реНрд╡реАрд░ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж


рдореИрдВ "рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ" рдФрд░ "рдЕрд╕рд╛рдорд╛рдиреНрдп рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ" рд╣рдм рдХреЗ рдмреАрдЪ рдЪрдпрди рдирд╣реАрдВ рдХрд░ рд╕рдХрд╛ред
рдПрдХ рдмрд╣реБрдд рд╣реА рдореБрд╢реНрдХрд┐рд▓ рд╡рд┐рдХрд▓реНрдк, рджреЛрдиреЛрдВ рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ред

Source: https://habr.com/ru/post/hi425145/


All Articles