paiza times

paizaがお届けする、テック・キャリア・マネジメント領域における「今必要な情報」を届けるWebメディア

logo

paizaがお届けする、テック・キャリア・マネジメント領域の「今必要な情報」を届けるWebメディア

例外処理で考慮すべきこととは?プログラミング時の考え方と注意点

f:id:paiza:20210805180818j:plain
f:id:paiza:20180910132940p:plainこんにちは。倉内です。

プログラミング学習には、独学でもある程度習得できる内容と、実務を経験しないとなかなか難しい内容とがあります。

後者の代表的なもののひとつとして「例外処理」があげられます。趣味で作っている場合はあまり考慮しなくても問題ないかもしれませんが、実際にサービスとして提供するとなれば、避けては通れない課題です。

paizaラーニングでも学習講座を提供していますが、初学者の方にはあまり馴染みのない内容かもしれません。ただ、これから開発系のエンジニアへの就職・転職を目指してプログラミング学習をされている方は触れておいてもよいでしょう。

今回はどう例外処理のコードを書くか以前に、そもそも例外とはなにか、例外処理に対する考え方などもお伝えしていきます。

もちろん開発するシステムの規模や社会的影響度合い、採用する開発言語、プロジェクトの方針はさまざまで、一概には言えない部分はありますが、ご自身で学ぶ際の足がかりにしていただければ幸いです。

例外処理を考える前に

そもそも例外とは

「例外とは何か」については、いろいろな考え方や意見がありますが、たとえば……

プログラミングでは、プログラムがある処理を実行している途中で生じ得る、設計から逸脱した状態を「例外」という。プログラムの利用者が対処するエラーとは異なり、例外は開発者が対処する。

(出典)例外 - Wikipedia

こう捉えると結構分かりやすいと思います。「想定内のエラー=例外」と表現する場合もあります。「正常な状態とは違うけど、あらかじめ想定することはできるもの」といった感じでしょうか。

具体例を見たほうがイメージがわきやすいので、よく見かける例外発生ケースを示しておきます。

  • ゼロ除算(ゼロで割り算すること)
  • 配列の範囲外へのアクセス
  • 存在しないファイルへのアクセス
  • データベースに接続できない

など

いずれも発生してしまうとシステムを操作するユーザー側からは対処ができない事象となります。

補足:コンパイルエラーと実行時エラー

コンパイル時にソースコード中の文法の誤りやスペルミスなどが原因で出るエラー(コンパイルエラー)と、実行時のエラーとは異なるものです。例外というのは実行時に発生するエラーのことを指します。

以下の記事では、コンパイル型言語であるC#の例外にフォーカスして解説していますのでよければごらんください。

paiza.hatenablog.com

例外処理とは

プログラムの実行時に例外が発生した際、現在の処理を中断し、別の処理をおこなってなんらかの対応をすることを例外処理といいます。

なぜ例外処理が必要か

f:id:paiza:20210806183109j:plain

さきほど挙げたような例外が発生すると、システム操作が続行不能になったり、データが破損したりする原因となります。

自分が趣味で開発して、自分だけが使うものであればそれほど問題ではないかもしれません。しかし実務においては、ユーザーに損害を与えることになってしまいます。そのため開発者が適切な例外処理をおこなう必要があるのです。

また、適切な例外処理がプログラムの安定稼働や品質を高めることにもつながります。

例外処理に対する考え方

例外処理の基本

例外発生時は

  • 例外に対処する
  • 例外を無視する

のどちらかで対応するというのが基本的な考え方です。

対処するとはつまり、システムの回復をはかったり、システムを安全に終了するための処理をおこなうことです。

一方、例外を無視することもできます。無視すると処理は続行できますが、明確な根拠をもって無視する必要があります。

そして例外を無視するというのは、たとえ例外が起きたとしても、知る必要・知らせる必要がなく、処理をそのまま続行させてもよいときに限ります。

実務においては、単に例外を無視して終わりとしていいケースはあまりないと思います。例外を無視することを「握りつぶす」と表現されることからも分かるとおり、それをやってしまうとデバッグが難しくなったり、のちのち重大なシステム障害につながったりする可能性があります。

例外処理設計の基本
  • 考えられる例外を洗い出し重要度や対処法を決める

例外の種類によって、発生頻度や影響の大きさは異なります。

中にはメッセージ表示だけすればいいものもあるかもしれませんし、リトライさせる処理を入れるべき場合もあるかもしれません。

想定される例外や、その重要度によって対処法を決めるべきです。

  • どこで例外処理をおこなうかを決める

たとえば、ファイルの読み込みをしているところ、外部入力処理をしているところ…など例外処理をどこでおこなうかを考えます。

例外処理を具体的にどこに書くべきなのか、どこで例外処理をすると回復できるのかを把握する必要があります。

(参考)段階的に理解する Java 例外処理 - Qiita
少し古い記事ではありますが、Javaに限らず、共通して大切なことが学べます。

プログラミング言語別に考える

プログラミング言語やフレームワークによっては、例外処理機構が用意されており、それを使って例外処理が実装できます。

言語による特徴もあるので、以降はpaizaラーニングの例外処理の講座を紹介しながらもう少し考えてみましょう。

paizaラーニングでは、Java、PHP、Ruby、Python、C#の各入門編講座で例外処理の動画講座を公開しています。プロの声優さんの解説と実践的な課題に挑戦することで「分かったつもり」で終わらせない、身につく学習が可能です。サンプルコードの実行だけおこないたい場合は、オンライン実行環境のpaiza.IOをご利用ください。

なお、初めてプログラミング学習をする方は、例外処理の前に基礎文法のレッスンの受講をおすすめします。言語別の初学者向け講座一覧はこちら

Java

20210805225717

本講座で学ぶ内容

f:id:paiza:20210805231023p:plain

f:id:paiza:20210805231010p:plain

Javaの例外処理の基本構文

f:id:paiza:20210806102418p:plain

たとえば、0除算の例外処理のコードはこのように書くことができます。

// 例外処理 - 0除算

public class Main {
    public static void main(String[] args) {

        System.out.println("Hello World");
        
        try {
            int number = 0;
            int answer = 100 / number;
            System.out.println(answer);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            System.out.println("Hello Java");
        }
    }
}

また、throwを使って意図的に例外を投げることができます。

// 例外処理 - throw

public class Main {
    public static void main(String[] args) {
        System.out.println("Hello World");

        try {
            int number = 2;
            int answer = 100 / number;
            System.out.println(answer);
            throw new Exception("強制エラー");
        } catch (ArithmeticException e) {
            System.out.println("0では、割り算できません。");
            e.printStackTrace();
        } catch (Exception e) {
            System.out.println("例外が発生しました。");
            e.printStackTrace();
        } finally {
            System.out.println("Hello Java");
        }
    }
}

動画講座では、解説とコードを書く演習がセットになっていますのでぜひチャレンジしてみてください。

PHP

20210805232312

本講座で学ぶ内容

よく目にするエラーを挙げて、それらを実際にコード書いて確認していきます。

f:id:paiza:20210805232910p:plain

構文はJavaとあまり変わりません。公式ドキュメントの例外のページもご参照ください。

たとえば、以下ではスラッシュ(/)区切りで日付を出力するプログラムに199x-01-01という日付フォーマットに沿わない値を入力し、catchで例外を捕捉しています。

<?php
echo "start\n";
try {
    $date = new DateTime("199x-01-01");
    echo $date->format('Y/m/d') . "\n";
} catch (Exception $e) {
    echo $e->getMessage() . "\n";
} finally {
    echo "end\n";
}
?>

これを実行してみると以下のようなメッセージが出力されます。

start
DateTime::__construct(): Failed to parse time string (199x-01-01) at position 0 (1): Unexpected character
end

エラーメッセージを出力することにより「期待していない文字列が渡された」ことが分かるようになりました。例外処理をすることにより、どこでどんな問題が起こっているかつかみやすくなります。

PHPでもthrowやfinallyを使った例外処理を書くことができます。動画講座で具体例を用いて学んでいきましょう。

Ruby

20210806094156

本講座で学ぶ内容

f:id:paiza:20210806094623p:plain

Rubyの例外処理の基本構文

f:id:paiza:20210806102127p:plain

たとえば、0除算の例外処理のコードはこのように書くことができます。

puts 1
begin
    number = 0
    answer = 100 / number
    puts answer
rescue ZeroDivisionError => e
    p e
ensure
    puts 2
end

また、raiseを使って意図的に例外を投げることができます。rescueと組み合わせることで、メソッドの呼び出し元にある例外処理を利用できます。

puts 1
begin
    puts 2
    raise Exception.new("意図的な例外")
    puts 3
rescue Exception => e
    puts "予期せぬエラーが発生しました"
    p e
    puts e.message
ensure
    puts 4
end

例外発生時に呼び出し元へその例外が伝わることについても具体例を用いて説明していますので、処理の流れが理解しやすくなっています。

Python

20210806095916

本講座で学ぶ内容

f:id:paiza:20210806101859p:plain

Pythonの例外処理の基本構文

f:id:paiza:20210806102102p:plain

たとえば、0除算の例外処理のコードはこのように書くことができます。

print(1)
try:
    number = 0
    answer = 100 / number
    print(answer)
except ZeroDivisionError as e:
    print(e)
finally:
    print(2)

また、raiseを使って意図的に例外を投げることができます。exceptと組み合わせることで、メソッドの呼び出し元にある例外処理を利用できます。

print(1)
try:
    print(2)
    raise BaseException("意図的な例外")
    print(3)
except BaseException as e:
    print("予期せぬエラーが発生しました")
    print(e)
finally:
    print(4)

Pythonの公式ドキュメントへのリンクも貼っておきます。講座で概要を押さえてからより深く理解をしたい場合や、実務で扱う際に参照できるようにしておくとよいでしょう。

C#

20210806103344

本講座で学ぶ内容

f:id:paiza:20210806103644p:plain

C#の例外処理の基本構文

f:id:paiza:20210806103654p:plain

たとえば、0除算の例外処理のコードはこのように書くことができます。

// 簡単な例外処理をしてみよう
using System;

class Lesson10
{
    public static void Main()
    {
        Console.WriteLine("Hello World");

        try
        {
            int number = 0;
            int answer = 100 / number;
            Console.WriteLine(answer);
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
        finally
        {
            Console.WriteLine("Hello C#");
        }
    }
}

また、throwを使って意図的に例外を投げることができます。

// throwで意図的に例外を投げよう
using System;

class Lesson10
{
    public static void Main()
    {
        Console.WriteLine("Hello World");

        try
        {
            int number = 2;
            int answer = 100 / number;
            Console.WriteLine(answer);
            throw new Exception("強制エラー");
        }
        catch (DivideByZeroException e)
        {
            Console.WriteLine("0では割り算できません");
            Console.Error.WriteLine(e);
        }
        catch (Exception e)
        {
            Console.WriteLine("例外が発生しました");
            Console.Error.WriteLine(e);
        }
        finally
        {
            Console.WriteLine("Hello C#");
        }
    }
}

上記のプログラムでは、number=2のときはthrowで強制的に例外を発生させています。実行してみると以下のようなメッセージが表示されます。

System.Exception: 強制エラー
  at Lesson10.Main () [0x0001e] in /workspace/Main.cs:15

number=0に変えてみるとどうでしょうか。今度はcatchで捕捉され、以下のようなメッセージが表示されます。

System.DivideByZeroException: Attempted to divide by zero.
  at Lesson10.Main () [0x0000e] in /workspace/Main.cs:13 

C#の講座では、例外のクラス構成についても解説しています。少し難しく感じるかもしれませんが、例外処理についてさらに理解を深めたい方は受講してみてください。

ここまで5つのプログラミング言語の例外処理をご紹介しました。基本的な構文だけ見ても似ている部分もあれば、言語によって異なる部分もありましたよね。ぜひ自分でコードを書きながら習得していただければと思います。

まとめ

例外とは何かから始まり、言語ごとの例外処理について学んできました。

なかなか独学では難しい内容ではありますが、学習サイトでも例外処理を扱っているところはありますし、初心者向けの参考書でも例外処理について章を割いているものもあります。

開発系のエンジニアに就職・転職を考えている方で、実務を見据えたプログラミング学習をしたいという方は例外処理を学んでおいて損はないと思います。

なお、各プログラミング言語のもっと基本的な内容を学びたい方は、全編無料で受講していただける「体験編」もご用意しています。そちらも合わせて活用してみてください!




paizaラーニング」では、未経験者でもブラウザさえあれば、今すぐプログラミングの基礎が動画で学べるレッスンを多数公開しております。

詳しくはこちら
paizaラーニング

そしてpaizaでは、Webサービス開発企業などで求められるコーディング力や、テストケースを想定する力などが問われるプログラミングスキルチェック問題も提供しています。

スキルチェックに挑戦した人は、その結果によってS・A・B・C・D・Eの6段階のランクを取得できます。必要なスキルランクを取得すれば、書類選考なしで企業の求人に応募することも可能です。「自分のプログラミングスキルを客観的に知りたい」「スキルを使って転職したい」という方は、ぜひチャレンジしてみてください。

詳しくはこちら
paizaのスキルチェック

paizaのおすすめコンテンツ

PPG proken プログラミングゲーム「初恋 プログラミング研究会〜海に行こうよ〜」 PPG Bingo プログラミングゲーム「コードレビューBINGO!!」
paiza転職 paiza新卒 EN:TRY paizaラーニング 記事内に記載している情報は、記事公開時点でのものとなります。 Copyright Paiza, Inc, All rights reserved.