Errorxãšã¯äœããã©ã®ããã«åœ¹ç«ã€ã
Errorxã¯ãGoã§ãšã©ãŒãåŠçããããã®ã©ã€ãã©ãªã§ãã å€§èŠæš¡ãããžã§ã¯ãã®ãšã©ãŒã¡ã«ããºã ã«é¢é£ããåé¡ã解決ããããã®ããŒã«ãšãããããæäœããããã®åäžã®æ§æãæäŸããŸãã

ã»ãšãã©ã®JoomãµãŒããŒã³ã³ããŒãã³ãã¯ãäŒç€Ÿèšç«ä»¥æ¥Goã§äœæãããŠããŸãã ãã®éžæã¯ãéçºã®åææ®µéãšãµãŒãã¹ã®åç¶æéã§å ±ãããŸãããGo2ã®èŠéãã«é¢ããçºè¡šãèžãŸãããšãä»åŸãåŸæããããšã¯ãªãã§ãããã Goã®äž»ãªé·æã®1ã€ã¯åçŽãã§ããããšã©ãŒãžã®ã¢ãããŒãã¯ããã®ååãä»ã«é¡ãèŠãªãã»ã©å®èšŒããŠããŸãã ãã¹ãŠã®ãããžã§ã¯ããååãªèŠæš¡ã«éããŠããªããããæšæºã©ã€ãã©ãªã®æ©èœãååã§ã¯ãªãããããã®åéã§ç¬èªã®ãœãªã¥ãŒã·ã§ã³ãæ¢ãå¿
èŠããããŸãã ãšã©ãŒãåŠçããããã®ã¢ãããŒããããŸããŸé²åããerrorxã©ã€ãã©ãªã¯ãã®é²åã®çµæãåæ ããŠããŸãã ç§ãã¡ã¯ãããã圌ãã®ãããžã§ã¯ãã®ãšã©ãŒãæ±ãããšã«ãŸã 倧ããªäžå¿«æãæããŠããªã人ã
ãå«ãå€ãã®äººã
ã«åœ¹ç«ã€ããšãã§ãããšç¢ºä¿¡ããŠããŸãã
Goã®ééã
errorxã«é¢ãã話ã«ç§»ãåã«ãããã€ãã®èª¬æãããå¿
èŠããããŸãã æåŸã«ããã°ã®äœãåé¡ã«ãªã£ãŠããŸããïŒ
type error interface { Error() string }
ãšãŠãç°¡åã§ãã å®éã«ã¯ãå€ãã®å Žåãå®è£
ã¯å®éã«ã¯ãšã©ãŒã®æååèšè¿°ä»¥å€ã®æ
å ±ãæã¡ãŸããã ãã®ãããªããããªãºã ã¯ããã¹ãå¿
ããããäŸå€çããªãã®ãæå³ããããã§ã¯ãªãã¢ãããŒãã«é¢é£ããŠããŸãã æãäžè¬çã«äœ¿çšããããšã©ãŒãæšæºã©ã€ãã©ãªã®NewïŒïŒã¯ããã®èãã«åœãŠã¯ãŸããŸãã
func New(text string) error { return &errorString{text} }
èšèªã®ãšã©ãŒã«ç¹å¥ãªã¹ããŒã¿ã¹ã¯ãªããéåžžã®ãªããžã§ã¯ãã§ããããšãæãåºããšãåé¡ãçºçããŸãããšã©ãŒãåŠçããããšã®ç¹æ§ã¯äœã§ããïŒ
ééããäŸå€ã§ã¯ãããŸãã ã å€ãã®äººãGoã«æ
£ãããšãæµæã«æµæããŠãã®éãã«ééããã®ã¯ç§å¯ã§ã¯ãããŸããã Goã§éžæãããã¢ãããŒãã説æãããµããŒãããæ¹å€ããå€ãã®åºçç©ããããŸãã ãããã«ãããGoã®ãšã©ãŒã«ã¯å€ãã®ç®çãããããã®ãã¡ã®å°ãªããšã1ã€ã¯ä»ã®èšèªã®äŸå€ãšãŸã£ããåãã§ãããã©ãã«ã·ã¥ãŒãã£ã³ã°ã§ãã ãã®çµæããããã®äœ¿çšã«é¢é£ããã¢ãããŒããšæ§æãéåžžã«ç°ãªã£ãŠããŠããåã衚çŸåãæåŸ
ããã®ã¯èªç¶ã§ãã
äœãæªãã®ïŒ
å€ãã®ãããžã§ã¯ãã¯ããã®ãŸãŸGoã®ãã°ãå©çšããŠãããããã«ã€ããŠå°ããå°é£ã¯ãããŸããã ãã ããã·ã¹ãã ã®è€éããå¢ãã«ã€ããŠãé«ãæåŸ
ããªããŠã泚æãåŒãå€ãã®åé¡ãçŸãå§ããŸãã è¯ãäŸã¯ããµãŒãã¹ã®ãã°ã®åæ§ã®è¡ã§ãïŒ
Error: duplicate key
ããã§ãæåã®åé¡ã¯ããã«æããã«ãªããŸãããããæå³çã«åŠçããªããšãäœããã®å€§èŠæš¡ãªã·ã¹ãã ã§ã¯ãæåã®ã¡ãã»ãŒãžã ãã§ã¯äœãåé¡ãªã®ããçè§£ããããšã¯ã»ãšãã©äžå¯èœã§ãã ãã®æçš¿ã«ã¯è©³çްãšåé¡ã®ããåºãæèãæ¬ ããŠããŸãã ããã¯ããã°ã©ããŒã®ééãã§ãããç¡èŠã§ããªãã»ã©é »ç¹ã«èµ·ãããŸãã å¶åŸ¡ã°ã©ãã®ãããžãã£ãããã©ã³ãå°çšã®ã³ãŒãã¯ãå®éã«ã¯åžžã«æ³šæãæãå¿
èŠããããå®è¡ã®äžæãå€éšã®åé¡ã«é¢é£ããããã¬ãã£ããã³ãŒãããããã¹ãã§ã«ããŒãããŸãã Goããã°ã©ã ã§if err != nil {return err}
ãã³ãã©ãç¹°ãè¿ãããé »åºŠã¯if err != nil {return err}
ãã®èŠèœãšããããã«å¯èœã«ããŸãã
å°ããªäœè«ãšããŠããã®äŸãèããŠã¿ãŸãããã
func (m *Manager) ApplyToUsers(action func(User) (*Data, error), ids []UserID) error { users, err := m.LoadUsers(ids) if err != nil { return err } var actionData []*Data for _, user := range users { data, err := action(user) if err != nil { return err } ok, err := m.validateData(data) if err != nil { return nil } if !ok { log.Error("Validation failed for %v", data) continue } actionData = append(actionData, data) } return m.Apply(actionData) }
ãã®ã³ãŒãã«ãšã©ãŒã衚瀺ãããã®ã¯ã©ã®ãããã®éãã§ããïŒ ããããããããGoããã°ã©ããŒã«ãã£ãŠå°ãªããšã1åã¯è¡ãããŸããã ãã³ãïŒ if err != nil { return nil }
ãåŒã®ãšã©ãŒã
ãã°ã«äžæçãªã¡ãã»ãŒãžã衚瀺ãããŠåé¡ã«æ»ããšããã¡ããã誰ãããã®ãããªç¶æ³ã«é¥ã£ãŠããŸãã åé¡çºçæã«ãã§ã«ãšã©ãŒåŠçã³ãŒãã®ä¿®æ£ãéå§ããã®ã¯éåžžã«äžå¿«ã§ãã ããã«ããã°ã®åæããŒã¿ã«ãããšãã©ã¡ãã®åŽãã³ãŒãã®ãã®éšåã®æ€çŽ¢ãéå§ãããã¯å®å
šã«äžæã§ãããå®éã«ã¯æ¹åãå¿
èŠã§ãã ããã¯ãã³ãŒããå°ãããå€éšäŸåé¢ä¿ã®æ°ãå°ãªããããžã§ã¯ãã§ã¯ãéåžžã«è€éãªããã«æãããããããŸããã ãã ããå€§èŠæš¡ãããžã§ã¯ãã®å Žåãããã¯å®å
šã«çŸå®çã§èŠçãªåé¡ã§ãã
èŠãçµéšã®ããããã°ã©ããŒããè¿ããããšã©ãŒã«äºåã«ã³ã³ããã¹ãã远å ããããšããŸãã ãããè¡ãåçŽãªæ¹æ³ã¯ã次ã®ãããªãã®ã§ãã
func InsertUser(u *User) error { err := usersTable.Insert(u) if err != nil { return errors.New(fmt.Sprintf("failed to insert user %s: %v", u.Name, err) } return nil }
è¯ããªã£ãã ããåºãã³ã³ããã¹ãã¯ãŸã äžæã§ãããå°ãªããšãã©ã®ã³ãŒãã§ãšã©ãŒãçºçããããèŠã€ããã®ãã¯ããã«ç°¡åã«ãªããŸããã ãã ãã1ã€ã®åé¡ã解決ãããããå¥ã®åé¡ããã£ããäœæããŠããŸããŸããã ããã§äœæããããšã©ãŒã«ããã蚺æã¡ãã»ãŒãžã¯å
ã®ãŸãŸã«ãªããŸãããããã®ã¿ã€ãã远å ã³ã³ãã³ããå«ãä»ã®ãã¹ãŠã¯å€±ãããŸããã
ãããå±éºãªçç±ã確èªããã«ã¯ãããŒã¿ããŒã¹ãã©ã€ããŒã§åæ§ã®ã³ãŒããæ€èšããŠãã ããã
var ErrDuplicateKey = errors.New("duplicate key") func (t *Table) Insert(entity interface{}) error {
IsDuplicateKeyError()
ãã§ãã¯ã¯ç Žæ£ãããŸãããããã¹ãããšã©ãŒã«è¿œå ããæç¹ã§ã¯ããã®ã»ãã³ãã£ã¯ã¹ã倿Žããã€ããã¯ãããŸããã§ããã ããã«ããããã®ãã§ãã¯ã«äŸåããã³ãŒããç ŽæããŸãã
func RegisterUser(u *User) error { err := InsertUser(u) if db.IsDuplicateKeyError(err) {
ããè³¢ãããŠç¬èªã®çš®é¡ã®ãšã©ãŒã远å ããå
ã®ãšã©ãŒãä¿åããŠãããšãã°Cause() error
ã¡ãœãããä»ããŠè¿ãããšãã§ããããã«ãããå Žåãåé¡ãéšåçã«ãã解決ããŸããã
- ãšã©ãŒåŠçã®ä»£ããã«ãçã®çç±ã
Cause()
ããšãç¥ãå¿
èŠããããŸãCause()
- å€éšã©ã€ãã©ãªã«ãã®ç¥èãæããæ¹æ³ã¯ãªããããã«æžããããã«ããŒé¢æ°ã¯åœ¹ã«ç«ããªããŸãŸã§ãã
- ç§ãã¡ã®å®è£
ã¯ã
Cause()
ãšã©ãŒã®çŽæ¥ã®åå Cause()
è¿ãããšãæåŸ
ã§ããŸãïŒããã§ãªãå Žåã¯nilïŒã æšæºããŒã«ã®æ¬ åŠãŸãã¯äžè¬ã«åãå
¥ããããŠããå¥çŽãéåžžã«äžå¿«ãªé©ããè
ãã
ãã ãããã®éšåçãªè§£æ±ºçã¯ãããçšåºŠãŸã§å«ããŠãå€ãã®ãšã©ãŒã©ã€ãã©ãªã§äœ¿çšãããŸãã Go 2ã«ã¯ããã®ã¢ãããŒããæ®åãããèšç»ããããŸãããããèµ·ãããšãäžèšã®åé¡ã«å¯ŸåŠããã®ãç°¡åã«ãªããŸãã
Errorx
以äžã§ã¯ãerrorxãæäŸãããã®ã«ã€ããŠèª¬æããŸãããæåã«ã©ã€ãã©ãªã®åºç€ãšãªãèæ
®äºé
ãå®åŒåããŠãã ããã
- 蚺æã¯ãªãœãŒã¹ã®ç¯çŽãããéèŠã§ãã ãšã©ãŒã®äœæãšè¡šç€ºã®ããã©ãŒãã³ã¹ã¯éèŠã§ãã ãã ããããžãã£ããã¹ã§ã¯ãªããã¬ãã£ããã¹ã衚ããã»ãšãã©ã®å Žåãåé¡ã®ã·ã°ãã«ãšããŠæ©èœããããããšã©ãŒå
ã®èšºææ
å ±ã®ååšã¯ããã«éèŠã§ãã
- ããã©ã«ãã§ã¹ã¿ãã¯ãã¬ãŒã¹ã ãšã©ãŒã蚺æã®å®å
šæ§ãšãšãã«ãªããªãããã«ã¯ãåªåã¯å¿
èŠãããŸããã ããã©ãããã远å ã®ã¢ã¯ã·ã§ã³ãå¿
èŠã«ãªãå¯èœæ§ããããšããæ
å ±ãïŒç°¡æœã«ããããããŸãã¯ããã©ãŒãã³ã¹äžã®çç±ã§ïŒæ£ç¢ºã«é€å€ããããšã§ãã
- ãšã©ãŒã®æå³ã ãšã©ãŒã®æå³ãã€ãŸãã¿ã€ãã倿§æ§ãããããã£ããã§ãã¯ããç°¡åã§ä¿¡é Œã§ããæ¹æ³ãå¿
èŠã§ãã
- 远å ã®ããããã åæ Œãããšã©ãŒã«èšºææ
å ±ã远å ããã®ã¯ç°¡åã§ããã®ã»ãã³ãã£ã¯ã¹ã®æ€èšŒãå°ç¡ãã«ããŠã¯ãªããŸããã
- ã·ã³ãã«ã ãšã©ãŒå°çšã®ã³ãŒãã¯ãå€ãã®å Žåãæ¥åžžçã«æžãããŠããããããããã䜿çšããåºæ¬çãªæäœã®æ§æã¯ã·ã³ãã«ã§ç°¡æœã§ãªããã°ãªããŸããã ããã«ããããã°ã®æ°ãæžããèªã¿ããããªããŸãã
- å°ãªãã»ã©å€ãã ã³ãŒãã®ãããããããšåäžæ§ã¯ããªãã·ã§ã³ã®æ©èœãšæ¡åŒµãªãã·ã§ã³ïŒãããã誰ã䜿çšããªãïŒãããéèŠã§ãã
- ãšã©ãŒã®ã»ãã³ãã£ã¯ã¹ã¯APIã®äžéšã§ãã åŒã³åºãã³ãŒãã§åå¥ã®åŠçãå¿
èŠãšãããšã©ãŒã¯ããããªãã¯ããã±ãŒãžAPIã®äºå®äžã®äžéšã§ãã é衚瀺ã«ãããæç€ºçã«ãããããå¿
èŠã¯ãããŸããããåŠçããã䟿å©ã«ããå€éšäŸåé¢ä¿ã®è匱æ§ãæžããããšãã§ããŸãã
- ã»ãšãã©ã®ãã°ã¯äžéæã§ãã å€éšãŠãŒã¶ãŒã«ãšã£ãŠããå€ãã®çš®é¡ã®ãšã©ãŒãäºãã«åºå¥ã§ããªãã»ã©ãåªããŠããŸãã ç¹å¥ãªåŠçãå¿
èŠãšããAPIã¿ã€ãã®ãšã©ãŒã®ããŒããããã³ãšã©ãŒèªäœãåŠçããããã«å¿
èŠãªããŒã¿ãããŒãããããšã¯ãåé¿ãã¹ãèšèšäžã®æ¬ é¥ã§ãã
ç§ãã¡ã«ãšã£ãŠæãé£ãã質åã¯æ¡åŒµæ§ã§ãããerrorxã¯ãåäœãä»»æã«ç°ãªãã«ã¹ã¿ã ã¿ã€ãã®ãšã©ãŒãå°å
¥ããããã®ããªããã£ããæäŸããå¿
èŠããããŸããããŸãã¯å¿
èŠãªãã®ãã¹ãŠãããã«äœ¿çšã§ããå®è£
ããããŸããïŒ 2çªç®ã®ãªãã·ã§ã³ãéžæããŸããã ãŸããerrorxã¯éåžžã«å®çšçãªåé¡ã解決ããŸããããã䜿çšããçµéšããããã®ç®çã®ããã«ã¯ããœãªã¥ãŒã·ã§ã³ãäœæããããã®ã¹ãã¢ããŒãã§ã¯ãªãããœãªã¥ãŒã·ã§ã³ãæã€æ¹ãè¯ãããšãããããŸãã 第äºã«ãã·ã³ãã«ããèæ
®ããããšã¯éåžžã«éèŠã§ãããšã©ãŒã«æ³šæãæãããªãããããšã©ãŒãæ±ãéã®ãã°ãããå°é£ã«ãªãããã«ã³ãŒããèšèšããå¿
èŠããããŸãã ãã®ããã«ã¯ããã®ãããªã³ãŒãããã¹ãŠåãããã«èŠããåãããã«åäœããããšãéèŠã§ããããšãå®è·µã瀺ããŠããŸãã
TL;ã¡ã€ã³ã©ã€ãã©ãªæ©èœã«ããDRïŒ
- ããã©ã«ãã§ãã¹ãŠã®ãšã©ãŒã®ã¹ã¿ãã¯ãã¬ãŒã¹äœæå Žæ
- ãšã©ãŒã®ã¿ã€ããã§ãã¯ãããã€ãã®çš®é¡
- äœãå£ããã«æ¢åã®ãšã©ãŒã«æ
å ±ã远å ããæ©èœ
- çºä¿¡è
ããå
ã®çç±ãé衚瀺ã«ããå Žåã¯ãå¯èŠæ§ã³ã³ãããŒã«ãå
¥åããŸã
- ãšã©ãŒåŠçã³ãŒãã®äžè¬åã¡ã«ããºã ïŒåéå±€ãç¹æ§ïŒ
- åçããããã£ã«ãããšã©ãŒã®ã«ã¹ã¿ãã€ãº
- æšæºãšã©ãŒã¿ã€ã
- ãšã©ãŒåŠçã³ãŒãã®å¯èªæ§ãåäžãããæ§æãŠãŒãã£ãªãã£
ã¯ããã«
errorxã䜿çšããŠäžèšã§åæããäŸãä¿®æ£ãããšã次ã®ããã«ãªããŸãã
var ( DBErrors = errorx.NewNamespace("db") ErrDuplicateKey = DBErrors.NewType("duplicate_key") ) func (t *Table) Insert(entity interface{}) error {
func InsertUser(u *User) error { err := usersTable.Insert(u) if err != nil { return errorx.Decorate(err, "failed to insert user %s", u.Name) } return nil }
IsDuplicateKeyError()
ã䜿çšããåŒã³åºãå
ã³ãŒãã¯å€æŽãããŸããã
ãã®äŸã§ã¯äœã倿ŽãããŸãããïŒ
ErrDuplicateKey
ããšã©ãŒã®ã€ã³ã¹ã¿ã³ã¹ã§ã¯ãªãåã«ãªããŸããã ããããã§ãã¯ããããšã¯ã³ããŒãšã©ãŒã«èæ§ããããŸã;æ£ç¢ºãªå¹³çãžã®è匱ãªäŸåæ§ã¯ãããŸãã- ããŒã¿ããŒã¹ãšã©ãŒã«ã¯ããŒã ã¹ããŒã¹ããããŸãã ãã®äžã«ã¯ãä»ã®ãšã©ãŒãååšããå¯èœæ§ãæãé«ãããã®ãããªã°ã«ãŒãåã¯èªã¿ãããã«åœ¹ç«ã¡ãå Žåã«ãã£ãŠã¯ã³ãŒãã§äœ¿çšã§ããŸã
- Insertã¯ãåŒã³åºãããšã«æ°ãããšã©ãŒãè¿ããŸãã
- ãšã©ãŒã«ã¯è©³çްãå«ãŸããŠããŸãã ãã¡ãããããã¯errorxãªãã§ãå¯èœã§ããã以åã«
IsDuplicateKeyError()
å¿
èŠã ã£ãåããšã©ãŒã€ã³ã¹ã¿ã³ã¹ãæ¯åè¿ãããå Žåã¯äžå¯èœã§ãã - ãããã®ãšã©ãŒã«ã¯ç°ãªãã¹ã¿ãã¯ãã¬ãŒã¹ãå«ãŸããå ŽåããããŸãã æ¿å
¥é¢æ°ãžã®ãã¹ãŠã®åŒã³åºãã§ã¯ããã®ç¶æ³ã¯åãå
¥ããããŸãã
InsertUser()
ã¯ãšã©ãŒããã¹ããè£è¶³ããŸãããå
ã®ãšã©ãŒãé©çšããŸããããã¯ãåŸç¶ã®æäœã®ããã«å®å
šã«ä¿æãããŸãIsDuplicateKeyError()
æ©èœããããã«ãªããŸããããšã©ãŒãã³ããŒããããDecorateïŒïŒã§å¥œããªã ãå€ãã®ã¬ã€ã€ãŒãäœæãããããŠããæãªãããããšã¯ãããŸããã
åžžã«ãã®ãããªã¹ããŒã ã«åŸãå¿
èŠã¯ãããŸããïŒ
- ãšã©ãŒã®ã¿ã€ãã¯åžžã«äžæã§ã¯ãããŸããïŒåãã¿ã€ããå€ãã®å Žæã§äœ¿çšã§ããŸã
- å¿
èŠã«å¿ããŠãã¹ã¿ãã¯ãã¬ãŒã¹ã³ã¬ã¯ã·ã§ã³ãç¡å¹ã«ããããšãã§ããæ¯åæ°ãããšã©ãŒãäœæããããšã¯ã§ããŸããããå
ã®äŸãšåããšã©ãŒãè¿ããŸãã ãããã¯ããããã»ã³ããã«ãšã©ãŒã§ããããã®äœ¿çšã¯ãå§ãããŸãããããšã©ãŒãã³ãŒãå
ã®ããŒã«ãŒãšããŠã®ã¿äœ¿çšããããªããžã§ã¯ãã®äœæãä¿åãããå Žåã«åœ¹ç«ã¡ãŸã
- æ ¹æ¬çãªåå ã®ã»ãã³ãã£ã¯ã¹ãsemantic
errorx.IsOfType(err, ErrDuplicateKey)
ç®ããé ãããå Žåã¯ã errorx.IsOfType(err, ErrDuplicateKey)
忢ãããæ¹æ³ããããŸãã - æ£ç¢ºãªåãšæ¯èŒãã以å€ã«ãåãã§ãã¯èªäœã®ä»ã®æ¹æ³ããããŸã
Godocã«ã¯ãããããã¹ãŠã«é¢ããè©³çŽ°ãªæ
å ±ãå«ãŸããŠããŸãã 以äžã§ã¯ãæ¥åžžã®äœæ¥ã«ååãªäž»ãªæ©èœã«ã€ããŠããå°ã詳ãã説æããŸãã
çš®é¡
errorxãšã©ãŒã¯äœããã®ã¿ã€ãã«å±ããŸãã ã¿ã€ããéèŠã§ã ç¶æ¿ããããšã©ãŒããããã£ãæž¡ãããå ŽåããããŸãã å¿
èŠã«å¿ããŠã»ãã³ãã£ã¯ã¹ãã¹ããè¡ââãããã®ã¯ã圌ãŸãã¯åœŒã®ç¹æ§ãä»ããŠã§ãã ããã«ãã¿ã€ãã®è¡šçŸåè±ããªååã¯ãšã©ãŒã¡ãã»ãŒãžãè£è¶³ããå Žåã«ãã£ãŠã¯ããã眮ãæããããšããããŸãã
AuthErrors = errorx.NewNamespace("auth") ErrInvalidToken = AuthErrors.NewType("invalid_token")
return ErrInvalidToken.NewWithNoMessage()
ãšã©ãŒã¡ãã»ãŒãžã«ã¯auth.invalid_token
ãå«ãŸãauth.invalid_token
ã ãšã©ãŒå®£èšã¯ç°ãªãããã«èŠããå ŽåããããŸãã
ErrInvalidToken = AuthErrors.NewType("invalid_token").ApplyModifiers(errorx.TypeModifierOmitStackTrace)
ãã®å®æœåœ¢æ
ã§ã¯ãã¿ã€ã修食åã䜿çšããŠãã¹ã¿ãã¯ãã¬ãŒã¹åéãç¡å¹ã«ãããã ãšã©ãŒã«ã¯ããŒã«ãŒã»ãã³ãã£ã¯ã¹ããããŸãããã®ã¿ã€ãã¯ãµãŒãã¹ã®å€éšãŠãŒã¶ãŒã«äžãããããã°å
ã®åŒã³åºãã¹ã¿ãã¯ã¯åœ¹ã«ç«ããªãã§ãããã ããã¯ä¿®åŸ©ããåé¡ã§ã¯ãããŸããã
ããã§ã¯ããšã©ãŒã®ããã€ãã®é¢ã§ãšã©ãŒãäºéã®æ§è³ªãæã€ããšãäºçŽã§ããŸãã ãšã©ãŒã®å
容ã¯ã蚺æã®ã»ããå€éšãŠãŒã¶ãŒïŒAPIã¯ã©ã€ã¢ã³ããã©ã€ãã©ãªãŠãŒã¶ãŒãªã©ïŒã®æ
å ±ãšããŠã䜿çšãããŸãã ãšã©ãŒã¯ãçºçããå
容ã®ã»ãã³ãã£ã¯ã¹ãäŒããææ®µãšããŠãããã³å¶åŸ¡ãç§»ãããã®ã¡ã«ããºã ãšããŠãã³ãŒãå
ã§äœ¿çšãããŸãã ãšã©ãŒã¿ã€ãã䜿çšããå ŽåããããèŠããŠããå¿
èŠããããŸãã
ãšã©ãŒäœæ
return MyType.New("fail")
ãšã©ãŒããšã«ç¬èªã®åãååŸããããšã¯å®å
šã«ãªãã·ã§ã³ã§ãã ãã¹ãŠã®ãããžã§ã¯ãã¯ãæ±çšãšã©ãŒã®ç¬èªã®ããã±ãŒãžãæã€ããšãã§ããäžéšã®ã»ããã¯ãerrorxãšãšãã«å
±éã®åå空éã®äžéšãšããŠæäŸãããŸãã ã»ãšãã©ã®å Žåãã³ãŒãã§ã®åŠçã䌎ããªããšã©ãŒãå«ãŸããŠãããäœãåé¡ãçºçããå Žåã®ãäŸå€çãªãç¶æ³ã«é©ããŠããŸãã
return errorx.IllegalArgument.New("negative value %d", value)
äžè¬çãªå ŽåãåŒã³åºãã®ãã§ãŒã³ã¯ããšã©ãŒããã§ãŒã³ã®æåŸã«äœæãããæåã«åŠçãããããã«èšèšãããŠããŸãã Goã§ã¯ããšã©ãŒã2ååŠçããã®ãæªã圢åŒãšèŠãªãããçç±ããªãããã§ã¯ãããŸãããããšãã°ããšã©ãŒããã°ã«æžã蟌ã¿ãã¹ã¿ãã¯ã®äžäœã«ãããè¿ããŸãã ãã ãããšã©ãŒãæäŸããåã«ããšã©ãŒèªäœã«æ
å ±ã远å ã§ããŸãã
return errorx.Decorate(err, "failed to upload '%s' to '%s'", filename, location)
ãšã©ãŒã«è¿œå ãããããã¹ãã¯ãã°ã«è¡šç€ºãããŸãããå
ã®ãšã©ãŒã®çš®é¡ã確èªããŠãåé¡ã¯ãããŸããã
æã
ãéã®ããŒãºãçºçããŸãããšã©ãŒã®æ§è³ªãäœã§ãããããã±ãŒãžã®å€éšãŠãŒã¶ãŒã¯ãããç¥ãã¹ãã§ã¯ãããŸããã ãã®ãããªæ©äŒãããã°ãå®è£
ã®äžéšã«è匱ãªäŸåé¢ä¿ãäœæã§ããŸãã
return service.ErrBadRequest.Wrap(err, "failed to load user data")
WrapãNewã®ä»£æ¿ãšããŠå¥œãŸããéèŠãªéãã¯ãå
ã®ãšã©ãŒããã°ã«å®å
šã«åæ ãããããšã§ãã ãããŠãç¹ã«ãæçšãªåæåŒã³åºãã¹ã¿ãã¯ããããããŸãã
åŒã³åºãã¹ã¿ãã¯ã«é¢ãããã¹ãŠã®å¯èœãªæ
å ±ãä¿åã§ããå¥ã®äŸ¿å©ãªããªãã¯ã¯ã次ã®ããã«ãªããŸãã
return errorx.EnhanceStackTrace(err, "operation fail")
å
ã®ãšã©ãŒãå¥ã®ãŽã«ãŒãã³ããçºçããå Žåããã®ãããªåŒã³åºãã®çµæã«ã¯ãäž¡æ¹ã®ãŽã«ãŒãã³ã®ã¹ã¿ãã¯ãã¬ãŒã¹ãå«ãŸãããã®æçšæ§ãç°åžžã«å¢å ããŸãã ãã®ãããªèª²é¡ãäœæããå¿
èŠãããã®ã¯æããã«ããã©ãŒãã³ã¹ã®åé¡ã«ãããã®ã§ãããã®ã±ãŒã¹ã¯æ¯èŒçãŸãã§ãããããèªäœãæ€åºãã人éå·¥åŠãéåžžã®ã©ãããé
ãããŸãã
Godocã«ã¯è©³çŽ°ãªæ
å ±ãå«ãŸããŠãããDecorateManyãªã©ã®è¿œå æ©èœã«ã€ããŠã説æããŠããŸãã
ãšã©ãŒåŠç
äœãããããšã©ãŒåŠçãæ¬¡ã®ããã«ãªãå ŽåïŒ
log.Error("Error: %+v", err)
ãããžã§ã¯ãã®ã·ã¹ãã å±€ã®ãã°ã«ãšã©ãŒãåºåããããšãé€ããŠãäœæããå¿
èŠã®ãããšã©ãŒãå°ãªãã»ã©è¯ãã§ãã çŸå®ã«ã¯ãããã§ã¯ååã§ãªãå Žåãããããããè¡ãå¿
èŠããããŸãã
if errorx.IsOfType(err, MyType) { }
ãã®ãã§ãã¯ã¯ãã¿ã€ãMyType
ãšã©ãŒãšãã®åã¿ã€ãã®äž¡æ¹ã§æåãã errorx.Decorate()
èæ§ããããŸãã ãã ããããã§ã¯ããšã©ãŒã®ã¿ã€ãã«çŽæ¥äŸåããŠããŸããããã¯ããã±ãŒãžå
ã§ã¯éåžžã«æ£åžžã§ãããå€éšã§äœ¿çšãããšäžå¿«ã«ãªãå ŽåããããŸãã å Žåã«ãã£ãŠã¯ããã®ãããªãšã©ãŒã®ã¿ã€ãã¯å®å®ããå€éšAPIã®äžéšã§ããããã®ãã§ãã¯ããšã©ãŒã®æ£ç¢ºãªã¿ã€ãã§ã¯ãªãããããã£ã®ãã§ãã¯ã«çœ®ãæãããå ŽåããããŸãã
å€å
žçãªGoãšã©ãŒã§ã¯ãããã¯ããšã©ãŒã®ã¿ã€ãã®ææšãšããŠæ©èœããåãã£ã¹ãã€ã³ã¿ãŒãã§ã€ã¹ãéããŠè¡ãããŸãã Errorxã¿ã€ãã¯ãã®æ¡åŒµæ©èœããµããŒãããŠããŸãããã代ããã«Trait
ã¡ã«ããºã ã䜿çšã§ããŸãã äŸïŒ
func IsTemporary(err error) bool { return HasTrait(err, Temporary()) }
errorxã«çµã¿èŸŒãŸãããã®é¢æ°ã¯ããšã©ãŒã«æšæºããããã£Temporary
ããããã©ããããã§ãã¯ããŸãã äžæçãªãã®ãã©ããã ãšã©ãŒã®ã¿ã€ããç¹æ§ã§ããŒã¯ããããšã¯ããšã©ãŒã®åå ã®è²¬ä»»ã§ãããããããéããŠãç¹å®ã®å
éšã¿ã€ããå€éšAPIã®äžéšã«ããããšãªããæçšãªã·ã°ãã«ãéä¿¡ã§ããŸãã
return errorx.IgnoreWithTrait(err, errorx.NotFound())
ãã®æ§æã¯ãå¶åŸ¡ãããŒãäžæããããã«ç¹å®ã®çš®é¡ã®ãšã©ãŒãå¿
èŠãªå Žåã«äŸ¿å©ã§ãããåŒã³åºãåŽã®é¢æ°ã«æž¡ãã¹ãã§ã¯ãããŸããã
ãã¹ãŠãããã«ãªã¹ããããŠããããã§ã¯ãããŸããããåŠçããŒã«ã¯è±å¯ã«ãããŸããããšã©ãŒã®åŠçã¯ã§ããéãåçŽãªãŸãŸã«ããŠããå¿
èŠãããããšãèŠããŠããããšãéèŠã§ãã ç§ãã¡ãé å®ããããšããŠããã«ãŒã«ã®äŸïŒ
- ãšã©ãŒãåãåã£ãã³ãŒãã¯åžžã«ãšã©ãŒå
šäœãèšé²ããå¿
èŠããããŸãã æ
å ±ã®äžéšãäžèŠãªå Žåã¯ããšã©ãŒãçæããã³ãŒãããããåŠçããããã«ããŸã
- ãšã©ãŒããã¹ããŸãã¯
Error()
颿°ã®çµæã䜿çšããŠã³ãŒãã§åŠçããããšã¯ã§ããŸããã ããã«ã¯ã¿ã€ã/ç¹æ§ãã§ãã¯ã®ã¿ãé©ããŠããŸãããŸãã¯ãerrorx以å€ã®ãšã©ãŒã®å Žåã¯ã¿ã€ãã¢ãµãŒã·ã§ã³ãé©ããŠããŸã - äœããã®ãšã©ãŒãç¹å¥ãªæ¹æ³ã§åŠçãããªããšããäºå®ã®ããã«ããã®ãããªåŠçãå¯èœã§ãããè¿œå æ©èœãæäŸããå Žåã§ãããŠãŒã¶ãŒã³ãŒããå£ããŠã¯ãªããŸãã
- ããããã£ã«ãã£ãŠãã§ãã¯ããããšã©ãŒã¯ãããããã»ã³ããã«ãšã©ãŒãããåªããŠããŸãã ãã®ãããªãã§ãã¯ã¯è匱ã§ã¯ãããŸãã
å€éšerrorx
ããã§ã¯ãããã¯ã¹ããã©ã€ãã©ãªãŠãŒã¶ãŒãå©çšã§ãããã®ã«ã€ããŠèª¬æããŸããããJoomã§ã¯ãšã©ãŒé¢é£ã³ãŒãã®æµžéãéåžžã«å€§ããã§ãã ãã®ã³ã°ã¢ãžã¥ãŒã«ã¯ã眲åã®ãšã©ãŒãæç€ºçã«åãå
¥ããäžæ£ãªãã©ãŒãããã®å¯èœæ§ãæé€ããããã«ããèªäœãå°å·ãããšã©ãŒãã§ãŒã³ãããªãã·ã§ã³ã§å©çšå¯èœãªã³ã³ããã¹ãæ
å ±ãæœåºããŸãã goroutinã䜿çšãããããã¯ã»ãŒããªåŠçãè¡ãã¢ãžã¥ãŒã«ã¯ããããã¯ãçºçããå Žåã«ãšã©ãŒãã¢ã³ããã¯ããå
ã®ã¹ã¿ãã¯ãã¬ãŒã¹ã倱ããã«ãšã©ãŒæ§æã䜿çšããŠãããã¯ã衚瀺ããæ¹æ³ãç¥ã£ãŠããŸãã ããã®ããã€ãã¯ãããããç§ãã¡ãå
¬éããŸãã
äºææ§ã®åé¡
errorxã䜿çšããŠãšã©ãŒãåŠçã§ããããšã«éåžžã«æºè¶³ããŠãããšããäºå®ã«ããããããããã®ãããã¯å°çšã®ã©ã€ãã©ãªã³ãŒãã®ç¶æ³ã¯çæ³ãšã¯ã»ã©é ããã®ã§ãã Joomã§ã¯ãerrorxã®ç¹å®ã®å®çšçãªåé¡ã解決ããŠããŸãããGoãšã³ã·ã¹ãã ã®èгç¹ããã¯ãããããã¹ãŠã®ããŒã«ã»ãããæšæºã©ã€ãã©ãªã«å«ããããšãæãŸããã§ãããã ãšã©ãŒã¯ããã®ãœãŒã¹ãå®éã«ãŸãã¯æœåšçã«å¥ã®ãã©ãã€ã ã«å±ããŠããããããšã€ãªã¢ã³ãšèŠãªãããå¿
èŠããããŸãã ãããžã§ã¯ãã§åãå
¥ããããŠãã圢åŒã§æ
å ±ãéãã§ããªãå¯èœæ§ããããŸãã
ãã ããä»ã®æ¢åã®ãœãªã¥ãŒã·ã§ã³ãšç«¶åããªãããã«ãããã€ãã®ããšãè¡ãããŠããŸãã
圢åŒ'%+v'
ãã¹ã¿ãã¯ãã¬ãŒã¹ïŒååšããå ŽåïŒãšãšãã«ãšã©ãŒãåºåããããã«äœ¿çšãããŸãã ããã¯Goãšã³ã·ã¹ãã ã®äºå®äžã®æšæºã§ãããGo 2ã®ãã©ãããã¶ã€ã³ã«ãå«ãŸããŠããŸãã
Cause() error
errorx , , , Causer, errorx Wrap().
æªæ¥
, Go 2, . .
, errorx Go 1. , Go 2, . , , errorx.
Check-handle , errorx , a Unwrap() error
Wrap()
errorx (.. , , Wrap
), . , , .
design draft Go 2, errorx.Is()
errorx.As()
, errors .
ãããã«
, , , - , . , API : , , . 1.0 , Joom. , - .
: https://github.com/joomcode/errorx
, !
