Goのエラーハンドリングが好き
Goとの出会い 自分がGoを触り始めたきっかけは、大学院1回生の時に研究室の先輩と一緒に出たISUCONでした。パフォーマンスの観点でGoがめっちゃいいらしいからGoで出ようってなって、Go Tourなんかで勉強してました。 当時なんでもGithubにpushしたい病だったので、よーわからんリポジトリもありました。 https://github.com/adshidtadka/go_tour エラーハンドリングがめんどくさい そもそもプログラミングをちゃんと始めたのが大学4回生のDonutsでのアルバイトで、経験が浅いなんちゃてプログラマーでした。つまり、エラーハンドリングなんてかったるいと思っているわけです。 そんなマインドでGoのコードを読むと、どんな関数もerrorを返してくることにびっくりします。 こんな感じで何か関数を呼び出すとすかさずerrorが帰ってくるので、いちいちエラーハンドリングを書くのがめんどくさく握りつぶしたいという思いに駆られることが幾度となくありました。 type Result struct{} func doSomething(code string) (*Result, error) { if code == "ok" { return &Result{}, nil } return nil, errors.New("エラーだよ") } func main() { _, err := doSomething("error") if err != nil { // エラーハンドリングをいちいち書かされる } } 他の言語の多くにはtry-catchの仕組みがあるので、こっちのが絶対便利とか思っていました。 type Result = {}; const doSomething = (code: string): Result => { if (code === "ok") { return {}; } throw new Error("エラーだよ"); }; const main = () => { try { const result = doSomething(); } catch (e) { // ここ1箇所でまとめてエラーハンドリングできる } }; やっぱりエラーハンドリングしたい 大学3年、社会人2年の時を経て考え方が変わりました。関数たちに対して思うことはエラーを勝手にthrowせずにちゃんと返して欲しいと思うようになりました。 その理由の一例がこちらです。最近プロダクトを開発する中で、不具合調査に時間がかかった例でもあります。 type Result = {}; const doSomething = (code: string): Result => { if (code === "ok") { return {}; } throw new Error("エラーだよ"); }; const main = () => { try { const result = doSomething(); const result2 = doSomething(); // こいつが呼ばれるかどうかわからない } catch (e) { } }; try句のコードは全て呼ばれるわけではないのです。勝手にジャンプしてcatch句にいく可能性を考えてコーディングする必要があります。try句には長い処理を書かない方が無難でしょう。 ...