예외 처리에 대한 기본적인 사항과 다중 블럭을 통한 예외처리는 이전의 포스팅을 참고한다.
[Delphi] 중첩 예외처리(try...except)
다중 혹은 중첩으로 예외를 처리하는 경우 결과는 어떻게될까? 결론은 예외처리 블럭 내에서 어떻게 처리하느냐에 따라 다르다. 단일 로직 내에서 중첩으로 예외를 처리하거나 예외처리가 되어
unhere.tistory.com
통상 예외가 발생했을 때 다음과 같이 예외처리 블럭을 만들고 Exception 객체를 통해 오류 내용을 확인한다.
try
mycode...
except
on E: Exception do
begin
ShowMessage('Error');
end;
end;
Exception 객체는 모든 Exception의 최상위 클래스이므로 하위 Exception 클래스에서 발생된 오류들도 모두 catch한다.
System.SysUtils에 보면 Exception클래스를 상속한 다양한 하위 Exception객체들을 확인할 수 있는데,
특정 오류시 마다 이를 구분하여 처리할 수 있도록 기능한다.
EPathTooLongException = class(Exception);
ENotSupportedException = class(Exception);
EDirectoryNotFoundException = class(Exception);
EFileNotFoundException = class(Exception);
EPathNotFoundException = class(Exception);
예를 들어 EDirectoryNotFoundException는 Exception을 상속하여 선언한 것으로
실행중에 디렉토리를 발견하지 못한 경우 다음과 같이 해당 예외를 발생시켜 처리할 수 있다.
procedure CheckPathFile(const MyFileName: string);
begin
if not DirectoryExists(ExtractFilePath(MyFileName)) then
raise EDirectoryNotFoundException.Create('Directory not found!');
if not FileExists(MyFileName) then
raise EFileNotFoundException.Create('Directory not found!');
end;
procedure MyProc;
begin
try
CheckPathFile('D:\MyDir\aaa.txt');
except
on E: Exception do ShowMessage(E.Message);
end;
end;
CheckPathFile프로시저를 보면
디렉토리가 없다면 raise로 EDirectoryNotFoundException을 생성하여 예외를 발생시키고,
파일이 없다면 raise로 EFileNotFoundException을 생성하여 예외를 발생시켜
어떤 종류의 예외가 발생된 것인지를 호출자에게 전달할 수 있다.
통상은 MyProc의 except블럭처럼 예외가 발생되었을 때 최상위 예외 객체인 Exception을 통해
어떤 종류의 예외가 되었건 모두 catch하여 오류 내용을 확인할 수 있도록 처리한다.
예외처리를 세분화하여 다음과 같이 각 예외의 경우에만 처리하도록 할수 있다.
procedure MyProc;
begin
try
CheckPathFile('D:\MyDir\aaa.txt');
except
on E: EDirectoryNotFoundException do
ShowMessage(E.Message + '디렉토리가 없네!!!');
on E: EFileNotFoundException do
ShowMessage(E.Message + '파일이 없네!!!);
end;
end;
발생된 예외가 EDirectoryNotFoundException이면 해당 예외처리가 호출되고 예외블럭을 종료하며,
EFileNotFoundException 이면 EDirectoryNotFoundException 예외처리가 호출되고 예외블럭을 종료한다.
즉, case문과 동일하게 발생된 예외 객체로 이동하여 예외를 처리하고 예외블럭을 종료한다.
그런데 만일 발생된 예외가 위에는 없는 EInOutError라면 어떻게 될까?
except블럭은 있지만 이를 처리할 해당 예외객체가 없으므로 아무런 예외처리도 오류도 발생하지 않는다.
어떤 예외된 던 일단 catch하여 처리하고 특정 예외인 경우에만 다르게 처리해야 한다면 어떻게 할까?
EInOutError = class(Exception)
public
ErrorCode: Integer;
end;
procedure MyProc;
begin
try
...
except
on E: Exception do
begin
if (E is EDirectoryNotFoundException) then
ShowMessage('디렉토리가 없네!!!')
else if (E is EFileNotFoundException) then
ShowMessage('파일이 없네!!!')
else if (E is EInOutError) then
ShowMessage(EInOutError(E).ErrorCode.ToString + ': ' + E.Message)
else
ShowMessage('뭔 에러야: ' + E.Message);
end;
end;
end;
위와 같이 최상위 객체인 Exception으로 예외처리 블럭을 만들고
내부에 Exception이 어떤 클래스인지 비교하여 각 예외별로 다르게 처리한다.
그리고 이외의 예외에 대해서는 일반적인 방식으로 Exception을 통해 예외를 처리할 수있다.
만일 EInOutError처럼 특정 멤버변수를 제공하는 경우 이를 이용하여 처리할 수도 있다.
'DogFoot > Delphi' 카테고리의 다른 글
[Delphi] Zip파일 압축/해제(ft. TZipFile) (0) | 2024.10.29 |
---|---|
[Delphi] 윈도우11 - 트레이아이콘 더블클릭 시 폼을 화면 최상위로 표시하기 (0) | 2023.07.19 |
[IdFTP] Indy FTP, Connection reset by peer: 10054 (0) | 2022.01.20 |
[Delphi] 중첩 예외처리(try...except) (0) | 2021.04.23 |
[FireDAC] MySQL/mariaDB 서버 오류 메시지 한글 깨짐 (0) | 2021.04.16 |
댓글