Golang Error Handling lesson by Rob Pike
Intro
ãã®è¨äºã¯ Go Advent Calendar 2014 ã® 15 æ¥ç®ã®è¨äºã§ãã
ä¾ãã°ãããã¯ã¼ã¯ã®ãã¬ã¼ã å¦ççãªãã®ãæ¸ãã¦ããå ´åã以ä¸ã®ãããªã³ã¼ããããã§ã¦ãã¾ãã
There are many codes like this, while writing a Network Frame Parser program.
var type uint8 err = binary.Read(r, binary.BigEndian, &type) if err != nil { return err } var length uint32 err = binary.Read(r, binary.BigEndian, &length) if err != nil { return err } ...
颿°ã®ä¸ã§ã¯ãåè¦ç´ ã®é·ãæ¯ã«èªã¿è¾¼ãã§ãèªã¿è¾¼ã¿ã«å¤±æãããã¨ã©ã¼ãå¼ã³åºãå ã«è¿ãã
each function reads length of value from socket and return error if failed.
æ¸ãè¾¼ãæã¯ãã»ã¼éã®ã³ã¼ãããã¼åãããã«æ¸ãã¾ãã
same things happens in writing to socket code.
ãããã«ãããä½åãç¶ã㨠DRY ã§ã¯ãªãããã¨ã©ã¼ã®å¦çãå¿ãã¦ãæ°ã¥ãã«ããã¨ããåé¡ãããã
same code appears again and again, it's not DRY. and also you probably forget handle error which you can't notice easily.
Go ã®ã¨ã©ã¼ã®åé¡ç¹
Go ã§ã¯å¤å¤ãè¿ãã¦ããã®æå¾ãã¨ã©ã¼ã«ãªãã¨ããå½¢å¼ããä¸è¬çã§ãããã¤åã¨ãã¦å®ç¾©ããã¦ããã
It's a basic way in go, returning multiple values from function, and error is last value of then.
ãã ããåé¡ã¯æ»ãå¤ã¯ãå¦çããªãã£ãã¨ãã¦ãã³ã³ãã¤ã«ãéããã¨ãã仿§ã«ãªã£ã¦ããã
but even if you don't care about return values, it's not compile error.
ã¤ã¾ãä¸ã®ä¾ã¯ã以ä¸ã®ããã«æ¸ãã¦ãã³ã³ãã¤ã«ãéãã
it means that compiler allows code like this.
// ignore return values binary.Read(r, binary.BigEndian, &type) binary.Read(r, binary.BigEndian, &length)
ãããçµæ§åé¡ã§ãåãå¿ãããã¨ãã³ã³ãã¤ã©ã ãã§ã¯åãããªãã
there is no notification when you forgot to process returned value even if it inclueds error.
ç¥ããããã°ãå¥éãã¼ã«ã使ã£ã¦æ¤æ»ãããããªãã
if you want to fined uncaught error, you need another linter tool.
ããããä¾ãã°æ»ãå¤ã®åå¾ãå¿
é ã«ããã¨ãããã¾ãåé¡ã§ãä¾ãã° fmt.Println
ãå¤å¤ãè¿ãã®ã§ããªã³ããããã°ã大å¤ãªãã¨ã«ãªãã
should compiler force programer to handle returned value ? I don't think so, for example fmt.Println
returns error too.
so its make difficult doing PRINT DEBUG.
_, _ := fmt.Println("print debug") _, _ := fmt.Println("here") _, _ := fmt.Println("")
How to solve?
ç¹ã« Read ã Write ã§ã®å¦çãå¢ãã¦è¡ã£ãå ´åãã³ã¼ãããã£ããããã¤ã¤ã Error ã確å®ã«å¦çããæ¹æ³ã«ã¤ãã¦ãèªåã®ä¸ã§ã¯è²ã ã¨è©¦è¡é¯èª¤ãã¦ããã
I tried some practice for make lots of Read/Write proces simple, and make sure process all Errors.
ã§ãå æ¥ http://gocon.connpass.com/event/9748/ ã®ããã«æ¥æ¥ãã¦ä¸ãã£ãã Rob Pike å çã«ããã®ä»¶ãèãã¦ã¿ãã
And I had a chance to ask Mr.Rob Pike about this problem at after party of http://gocon.connpass.com/event/9748/ in Japan last month.
ãã㦠Rob å çã¯ã俺ã®ãã¼ãã¼ã(æ²ãããã¨ã« vim ããå ¥ã£ã¦ãªãã£ããã)ã§ãå®éã«æ¸ããªãã説æãã¦ããã¾ããï¼ï¼ãªãã¨ãã幸éã
and then, Mr.Rob taught me with writting a code on my Mac(unfortunately, I installed only vim...), what's a presious happenig !!
ããå
çã«ã¨ã©ã¼ãã³ããªã³ã°ã®ãã¨ã«ã¤ãã¦èããããã¡ãã£ã¨ãã¼ãã¼ã貸ãï¼ãã£ã¦ãã£ã¦ä¿ºã® PC ã§ã³ã¼ãæ¸ãã¦æå°ãã¦ãã ãã£ãããããªè³ç¦ã¯ãªããçãã¦ã¦è¯ãã£ãã§ãã #gocon
— Jxck (@Jxck_) 2014, 11æ 30
å çã説æãã¤ã¤æ¸ãã¦ãããã³ã¼ãããã¡ãã
Mr.Rob show me the code like this.
type errWriter struct { w io.Writer err error } func (e *errWriter) Write(p []byte) { if e.err != nil { return } _, e.err = e.w.Write(p) } func (e *errWriter) Err() error { return e.err } func do() { ew := &errWriter{ w: ... } ew.Write(buf) ew.Write(buf) ... ... if ew.Err() != nil { return ew.Err() } return nil }
Writer ã® Wrapper ã«ãªã£ã¦ãã¦ãã¨ã©ã¼ãçºçããæã¯å é¨ã§ãããä¿æãã¤ã¤ã以éã®å¦çã¯å ¨ã¦ãã¹ãããã
Write a wrapper struct of Writer. while processing, hold a error if happened and pass all Write() below.
æå¾ã«ã¨ã©ã¼ã®æç¡ã確èªãããã¨ã§ãã¨ã©ã¼å¦çãä¸ã«æã«ã¾ã¨ããã
end of the function, check and process the error in struct. this gathers error handling in one place.
ã¨ãããã Writer 㨠Reader ã«ã¤ãã¦ä½ã£ã¦ããã°ã Write ã Read ã®å¦çãå¤ããªãã»ã©ã¡ãªããã大ãããªãã
prepare a struct for Writer and Reader has a merit when you write a lot of Write()/Read() process.
ç´ æ´ã ãã© Go ãããã³ã¼ãã§ããã
so simple but powerful as golang way :)
Movie
ãã£ããè¦ã¥ãããã©ãã¶ã£ã¡ããå¾ã§äººã«è¦ããæ ååããããããã®å ´ã§ããå çã®è©±èãæ¹ã大äºã ãããã§ä¸æ¯ä¸æ¯ã ã£ãã®ã§ãã¾ãé°å²æ°ã ãã¿ã¦ãã ããã
Sorry for hard to watch, but it's more important to see and hear Mr Robs Exmplain haha. be patient :)
Mr. Rob Rike taught me about practice of error handling in Go at GoCon 2014 from Jxck on Vimeo.
Special Thanks
thanks for writing a code on my laptop @rob_pike , and we proud that you join and had keynote on our #gocon. have a nice stay in Japan!
— Jxck (@Jxck_) 2014, 11æ 30
message from @rob_pike thanks !! #gocon pic.twitter.com/RNsp4SsA7z
— Jxck (@Jxck_) 2014, 11æ 30
thanks Mr.Rob Pike !
from your student Jxck :)