Language/C#

[C#] 예외 처리

달별선장 2023. 9. 3. 13:03
728x90

1. try ~ catch 문의 다양한 형태의 예

using System;

namespace HelloWorld
{
    class Program
    {
        static void Main(string[] args)
        {
            int a = 15;
            decimal b = 88m;
            float c = 20.3f;

            // [1]
            try
            {
                a = Convert.ToInt32(b / (decimal)c);
            } catch
            {
                Console.WriteLine("모든 예외를 잡고 싶을 때");
            }

            // [2]
            try
            {
                a = Convert.ToInt32(b / (decimal)c);
            } catch (Exception e) // 모든 예외의 최상위 예외 클래스
            { // 혹은 다른 Exception 종류 (특정 예외를 잡고 싶을 때)
                Console.WriteLine(e); // 예외 로그를 출력
            }

            // [3] 예외처리 구문의 다른 형식의 예 (catch 문 여러개)
            try
            {
                a = Convert.ToInt32(b / (decimal)c);
            }
            catch (ArgumentException)
            {
                Console.WriteLine("첫번째 예외 케이스");
            }
            catch (ApplicationException)
            {
                Console.WriteLine("두번째 예외 케이스");
            }

            // [4] finally 구문을 추가하면, 성공이든, 예외이든 상관 없이
            //     finally 구문 내의 코드를 실행한다.
            try
            {
                a = Convert.ToInt32(b / (decimal)c);
            }
            catch
            {
                Console.WriteLine("모든 로그를 잡고 싶을 때 파라미터를 받지 않는다.");
            }
            finally
            {
                Console.WriteLine("마지막으로 꼭 실행되는 구문은 finally 안으로");
            }
        }
    }
}

2. try ~ catch 문 내  throw 문 사용의 다양한 예

catch 문에서 선언된 Exception 을 다시 상위 호출자로 보내고 싶을 때 throw 를 사용한다.

 

1) throw 문 다음에 catch 에서 전달받은 Exception 파라미터를 사용하는 경우

throw e;

사용하지 않는 것이 좋다.

 

2) throw 문 다음에 새 예외 클래스를 생성해서 전달하는 경우

throw new MyApplicationCommonException();

catch 에서 잡은 예외를 throw 문에서 새로 생성한 예외 클래스에 그 정보를 담아서 보낸다.

이때, InnerException 을 포함하지 않으면 기존 Exception 정보를 유실할 가능성이 있다.

 

따라서, 다음과 같은 형태로 코딩하는 것이 좋다.

throw new MyApplicaionCommonException(e);

위 방법으로 코딩하면 InnerException 이 소스의 어느 라인에서 에러가 발생했는지 알려준다.

 

3) throw 문 다음에 아무 것도 없는 경우

catch 문에서 잡힌 Exception을 그대로 상위 호출 함수에게 전달한다.

using System;

namespace HelloWorld
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                exceptionCode(); // 호출했는데, 호출된 메서드에서 에러 발생
            } catch (Exception e)
            {   
                Console.WriteLine("Exception");
                throw; // 상위 호출자에게 에러 전달
                Console.WriteLine("Finally Code End"); // 코드 실행 불가함
            } finally
            {
                Console.WriteLine("Code End");
            }
        }

        static void exceptionCode ()
        {
            Console.WriteLine("Code Start"); // 실행
            int[] nums = new int[5];
            nums[0] = 1;
            nums[2] = 3;
            nums[5] = 6;
            foreach (int num in nums)
            {
                Console.WriteLine($"num : {num}"); // 예외 발생
                                                   // 호출자 함수 Main 에서 예외 메지지
                                                   // 상위 함수인 exceptionCode()로 전달
            }

            Console.WriteLine("Foreach Code End"); // 실행되지 않음
        }
    }
}

실행 결과 :

 

728x90