カテゴリ: Go言語 更新日: 2025/12/10

Go言語のcontextパッケージとエラーハンドリングの関係を解説!初心者でもわかる使い方

Go言語のcontextパッケージとエラーハンドリングの関係を解説
Go言語のcontextパッケージとエラーハンドリングの関係を解説

先生と生徒の会話形式で理解しよう

生徒

「先生、Go言語のcontextパッケージって何ですか?エラーハンドリングとどう関係があるんでしょう?」

先生

「contextパッケージは、処理の途中で『やめてください』や『時間切れ』などの合図を送るための仕組みです。エラーハンドリングと関係があるのは、処理がキャンセルされたりタイムアウトしたときに、その情報をエラーとして受け取るからです。」

生徒

「キャンセルとかタイムアウトってよくわからないです。もう少しわかりやすく教えてください!」

先生

「例えば、長い間かかる処理をコンピュータに頼んだとします。でも時間がかかりすぎると困るので、『10秒たったらやめてね』と伝えたい。contextパッケージを使うと、そういう『やめてください』の合図を出せるんですよ。」

生徒

「なるほど。じゃあ、その合図が届いたらどうやってエラーとして扱うんですか?」

先生

「それがエラーハンドリングのポイントです。contextがキャンセルやタイムアウトを知らせると、プログラムはその情報をエラーとして受け取って処理を中断します。実際の使い方をコード例で見てみましょう!」

1. contextパッケージとは?

1. contextパッケージとは?
1. contextパッケージとは?

Go言語のcontextパッケージは、複数の関数や処理の間で「処理をキャンセルする」「処理の期限を設定する」などの情報を共有するための仕組みです。

これは、特にWebサーバーやネットワーク処理など、長時間かかる処理を途中で止めたいときに役立ちます。

2. なぜエラーハンドリングと関係があるの?

2. なぜエラーハンドリングと関係があるの?
2. なぜエラーハンドリングと関係があるの?

contextは処理の中断を知らせるために使われますが、その中断はエラーとして扱います。つまり、処理がキャンセルされたりタイムアウトになった場合は、context.Canceledcontext.DeadlineExceededという特別なエラーが返ってきます。

これらのエラーを受け取ることで、プログラムは「処理が途中で止まった」ことを認識し、適切な対応ができるようになります。

3. 簡単なキャンセルの例

3. 簡単なキャンセルの例
3. 簡単なキャンセルの例

次のコードは、context.WithCancelを使って、処理をキャンセルする例です。


package main

import (
    "context"
    "fmt"
    "time"
)

func main() {
    ctx, cancel := context.WithCancel(context.Background())

    go func() {
        time.Sleep(2 * time.Second)
        cancel() // 2秒後にキャンセルを通知
    }()

    select {
    case <-time.After(5 * time.Second):
        fmt.Println("処理が完了しました")
    case <-ctx.Done():
        fmt.Println("処理がキャンセルされました:", ctx.Err())
    }
}

この例では、2秒後にキャンセルの合図が送られ、ctx.Done()が反応します。そのときのエラーがctx.Err()で取得でき、「処理がキャンセルされました」と表示されます。

4. タイムアウト付きのcontext例

4. タイムアウト付きのcontext例
4. タイムアウト付きのcontext例

今度は、処理に時間制限(タイムアウト)を設ける例です。context.WithTimeoutを使います。


package main

import (
    "context"
    "fmt"
    "time"
)

func main() {
    ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
    defer cancel()

    select {
    case <-time.After(5 * time.Second):
        fmt.Println("処理が完了しました")
    case <-ctx.Done():
        fmt.Println("処理がタイムアウトしました:", ctx.Err())
    }
}

ここでは3秒でタイムアウトし、5秒かかる処理は途中で止まります。エラーとしてcontext.DeadlineExceededが返されます。

5. contextのエラーを使った実際のエラーハンドリング

5. contextのエラーを使った実際のエラーハンドリング
5. contextのエラーを使った実際のエラーハンドリング

実際にcontextのエラーを使うときは、ctx.Err()をチェックして、どんな理由で中断されたのかを判断します。例えばこうです。


if err := ctx.Err(); err != nil {
    if err == context.Canceled {
        fmt.Println("処理はキャンセルされました")
    } else if err == context.DeadlineExceeded {
        fmt.Println("処理はタイムアウトしました")
    } else {
        fmt.Println("その他のエラー:", err)
    }
}

こうすることで、キャンセルとタイムアウトの違いを分けて処理できます。

6. 覚えておきたいポイント

6. 覚えておきたいポイント
6. 覚えておきたいポイント
  • Goのcontextパッケージは、処理のキャンセルやタイムアウトを伝えるための仕組み
  • キャンセルやタイムアウトはcontext.Canceledcontext.DeadlineExceededというエラーで通知される
  • エラーハンドリングでctx.Err()を確認し、適切な対応を行うことが大切
  • 特にWebやネットワーク処理で長時間の処理を安全に中断するためによく使われる

Go言語を基礎からスッキリ学びたい人や、 文法だけでなく「実用的な使い方」まで押さえたい人には、 定番の入門書がこちらです。

基礎からわかるGo言語をAmazonで見る

※ Amazon広告リンク

まとめ

まとめ
まとめ

contextとエラーハンドリングの関係を深く理解するために

今回の記事では、Go言語のcontextパッケージがどのように動作し、エラーハンドリングとどのように結びついているのかを体系的に学びました。contextは「ただの便利ツール」ではなく、長時間の処理や複数の関数が連携する場面で欠かせない仕組みであり、特にキャンセルやタイムアウトが発生した際に、明確なエラーとして通知される点がとても重要です。 初心者が最初につまずきやすいのは、contextが返すエラーが「処理中に発生したエラー」ではなく「処理を続けられない理由」である点です。つまり、context.Canceledはユーザーやプログラム側の都合による中断、context.DeadlineExceededは時間切れ、というように、それぞれが明確な意味を持っています。

また、contextは複数の処理全体で共有されるため、一つの合図が複数の関数に影響することがあります。例えばWebサーバーでは、ユーザーがページ遷移やキャンセル操作を行った瞬間、contextからキャンセルの合図が送られ、関連する処理がすべて安全に停止します。この仕組みにより、不要な処理を無駄に続けることなく、サーバー資源を効率よく保つことができます。 こうした動きは、エラーハンドリングの正しい理解がないと捉えにくいため、今回の例を通してcontextのエラーをしっかり読み取れるようになることが大きな一歩になります。

contextのキャンセルとタイムアウトを使った実践的なサンプル

ここでは、contextを使った実践的なサンプルをもう一つ紹介します。これは複数の処理を同時に動かしつつ、途中でキャンセルの合図が来たときに全体を安全に止める例です。


package main

import (
    "context"
    "fmt"
    "time"
)

func longTask(ctx context.Context, name string) {
    for i := 1; i <= 5; i++ {
        select {
        case <-ctx.Done():
            fmt.Println(name, "は中断されました:", ctx.Err())
            return
        default:
            fmt.Println(name, "を実行中...", i)
            time.Sleep(1 * time.Second)
        }
    }
    fmt.Println(name, "が正常に完了しました")
}

func main() {
    ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
    defer cancel()

    go longTask(ctx, "処理A")
    go longTask(ctx, "処理B")

    time.Sleep(6 * time.Second)
    fmt.Println("メイン処理終了")
}

このサンプルでは、複数の処理が同じcontextを共有しており、3秒でタイムアウトした瞬間、両方の処理が中断されます。「途中でやめなければならない」という場面は実際のソフトウェアでもよくあり、contextを理解しておくことで、効率的で安全なコードを書くことができるようになります。

contextのエラーを扱うための思考法

contextを使ったエラーハンドリングで特に大切なことは「中断された理由を正しく読み取る」ことです。キャンセルなのか、タイムアウトなのか、その他の理由によるものなのかを切り分けることで、次に取るべき行動を適切に選ぶことができます。 例えばユーザーが明示的にキャンセルした場合には処理を中断してよいですが、タイムアウトの場合は「どうすれば改善できるか」「時間を延ばすべきか」「新しい対処が必要か」など、考えるべきポイントが異なるためです。

こうした細やかな判断ができるようになると、contextを活用したエラーハンドリングが強力な味方になり、Web開発やバッチ処理、ネットワーク通信など、さまざまな分野で安定したプログラムを作れるようになります。 Go言語を学び始めた初心者にとっても、この仕組みを早い段階で理解しておくと、後々のコード設計が格段にしやすくなります。

先生と生徒の振り返り会話

生徒

「contextのおかげで、キャンセルやタイムアウトがどう扱われているのか分かりました!エラーとして受け取ることで処理を安全に止められるんですね。」

先生

「その通りです。contextは複雑なようでいて、動きを理解するととても便利な仕組みなんですよ。使いこなせるようになると、ネットワーク処理や並行処理が格段に書きやすくなります。」

生徒

「キャンセルとタイムアウトがエラーでわかるのは、後の処理を安全に続けるためなんですね。コード例も分かりやすかったです!」

先生

「これからはcontextを使った処理を書きながら、実際にどんなタイミングでエラーが返るのか確かめてみると良いでしょう。経験を重ねるほど理解がどんどん深まりますよ。」

関連セミナーのご案内

【超入門】ゼロから始めるGo言語プログラミング:最速で「動くアプリ」を作るマンツーマン指導

「プログラミングの仕組み」が根本からわかる。Go言語でバックエンド開発の第一歩を。

本講座を受講することで、単なる文法の暗記ではなく、「プログラムがコンピュータの中でどう動いているか」という本質的な理解につながります。シンプルながら強力なGo言語(Golang)を通じて、現代のバックエンドエンジニアに求められる基礎体力を最短距離で身につけます。

具体的な開発内容と環境

【つくるもの】
ターミナル(黒い画面)上で動作する「対話型計算プログラム」や、データを整理して表示する「ミニ・ツール」をゼロから作成します。自分の書いたコードが形になる感動を体験してください。

【開発環境】
プロの現場でシェアNo.1のVisual Studio Code (VS Code)を使用します。インストールから日本語化、Go言語用の拡張機能設定まで、現場基準の環境を一緒に構築します。

この60分で得られる3つの理解

1. 環境構築の完全な理解

「なぜ動くのか」という設定の仕組みを理解し、今後の独学で詰まらない土台を作ります。

2. Go言語の基本構造(変数・型)

データの種類やメモリの概念など、他言語にも通じるプログラミングの本質を学びます。

3. 読みやすいコードの書き方

ただ動くだけでなく、誰が見ても分かりやすい「綺麗なコード」を書くための考え方を伝授します。

※本講座は、将来的にバックエンドエンジニアクラウドインフラに興味がある未経験者のためのエントリー講座です。マンツーマン形式により、あなたの理解度に合わせて進行します。

セミナー画像

初めてのGo言語を一緒に学びましょう!

関連記事:
カテゴリの一覧へ
新着記事
New1
Go言語
Go言語のwhile的なforループの使い方!条件式ループの基本を解説
New2
Go言語
Go言語プログラムの実行方法まとめ!VSCode・ターミナルでの実行手順を解説
New3
Swift
Swift意味とは?プログラミング言語・金融・鳥の違いを徹底解説
New4
Swift
Swift 戻り値の扱い方と複数戻り値の返し方|初心者でも分かる関数の基本
人気記事
No.1
Java&Spring記事人気No1
Go言語
Go言語でリダイレクト処理を行う方法(http.Redirect)を初心者向けに解説
No.2
Java&Spring記事人気No2
Swift
Swift開発環境の構築方法を徹底解説!Xcode・Windows・Linux対応
No.3
Java&Spring記事人気No3
Kotlin
Android Studioのインストール手順と初期設定を初心者向けに完全解説!
No.4
Java&Spring記事人気No4
Kotlin
Gradleファイル(build.gradle.kts)の書き方と役割をやさしく解説!Kotlin初心者向け完全ガイド
No.5
Java&Spring記事人気No5
Go言語
Go言語のgo.modファイル完全ガイド!初心者でもわかる仕組みと書き方
No.6
Java&Spring記事人気No6
Go言語
Go言語で条件式を1行で書くコツ!三項演算子の代替と短縮記法
No.7
Java&Spring記事人気No7
Swift
Swift Playgroundの使い方を完全解説!初心者に最適な学習環境の始め方
No.8
Java&Spring記事人気No8
Kotlin
Kotlinの演算子一覧と使い方!算術・比較・論理演算子の基本を解説