Exceptions

김하람·2022년 3월 18일
0

flutter

목록 보기
1/17

Exceptions

의미: exceptions는 예상치 못한 일이 발생했음을 나타내는 오류이다.
기능: dart code는 exceptions를 throw 하고 catch할 수 있다.
특징: dart는 exception과 error types를 제공하지만, null이 아닌 객체만 throw 할 수 있다.

exceptions를 다루기 위해 알아야 하는 용어

throw

exception발생 시 객체 또는 코드 등을 반환할 수 있다.
//일단 에러를 던져본다고 생각

throw 사용 코드 예)

//example 1
throw FormatException('Expected at least 1 section');
//example 2
throw 'Out of llamas!';

example 1 사용을 권장한다.

  • 에러 타입을 나타내는 implemeter 사용하는 것 권장.
    why?
    implemeter에 다양한 exception과 error의 종류가 있기 때문.

catch

catch는 다양한 exception상황을 제시해서 특정 상황의 에러 상황을 제어한다.
-> 예외를 다시 발생시키지 않는 한 예외가 전파되지 않는다.
//exception을 catch 한다고 이해함

catch문을 여러 개 쓰면 다양한 종류의 에러 상황 제어 가능하다.
오류 상황 앞에 on을 쓰거나, catch를 사용한다.

<예시코드1>

try {
  breedMoreLlamas();
} on OutOfLlamasException {
  buyMoreLlamas();
}
//OutofLiamasException이라는 오류가 생기면 buyMoreLlamas()실행.

<예시코드2>

try {
  breedMoreLlamas();
} on OutOfLlamasException {
  // 지정해둔 특정 오류 상황(OutOfLlamas라는 오류 상황) 처리
  buyMoreLlamas();
} on Exception catch (e) {
  // exception 타입으로 지정한 오류 처리 
  // (위에 선언한 OutOfLlamasException는 제외)
  print('Unknown exception: $e');
} catch (e) {
  // 타입이 특정하게 지정되지 않은 나머지 오류 처리
  print('Something really unknown: $e');
}
//한 경우씩 위에서부터 걸러서 내려온다고 생각

rethrow

rethrow는 오류를 재전파한다. 함수의 오류를 볼 수 있게 하기 위해서 재전파 하는 것이다.
예외를 완전히 처리할 수 없는 경우 사용한다.

<예시코드>

void misbehave() {
  try {
    dynamic foo = true;
    print(foo++); // 만약 여기서 런타임 오류가 났다면
  } catch (e) { // 여기서 오류를 catch하고,
    print('misbehave() partially handled ${e.runtimeType}.');
    rethrow; // call한 함수(해당 예시에서는 main함수)가 이 오류 볼 수 있도록 재전파
  }
}

void main() {
  try {
    misbehave(); // rethrow로 위에서 찾은 에러가 재전파되어 발생.
  } catch (e) { // 에러를 catch
    print('main() finished handling ${e.runtimeType}.');
  }
}

finally

finally는 예외 발생의 여부와 관계 없이 일부 코드가 실행되게 할 때 사용한다.

finally는 크게 두 가지 상황으로 나뉜다.

1. catch가 있는 경우

에러 상황에 알맞는 catch문이 있으면, catch문을 먼저 실행하고 finally 실행
실행 순서: catch문 -> finally

<예시코드>

try {
  breedMoreLlamas();
} catch (e) {
  print('Error: $e'); // 에러를 먼저 제어한다.
} finally {
  cleanLlamaStalls(); // 그 다음, 함수를 실행한다.
}

2. catch가 없는 경우

에러 상황에 알맞는 catch문이 없으면 exception이 있어도 finally를 실행한다.
실행 순서: finally -> exception

<예시코드>

try {
  breedMoreLlamas();
} finally {
    // 에러가 발생하더라도 아래 호출된 함수 실행
  cleanLlamaStalls();
  //catch문이 없으므로 에러가 재전파 된다.
}

exception code example

typedef VoidFunction = void Function();

class ExceptionWithMessage {
  final String message;
  const ExceptionWithMessage(this.message);
}

// Call logException to log an exception, and doneLogging when finished.
abstract class Logger {
  void logException(Type t, [String? msg]);
  void doneLogging();
}

void tryFunction(VoidFunction untrustworthy, Logger logger) {
  // Invoking this method might cause an exception. Catch and handle
  // them using try-on-catch-finally.
  untrustworthy();
}

solution code

typedef VoidFunction = void Function();

class ExceptionWithMessage {
  final String message;
  const ExceptionWithMessage(this.message);
}
// Call logException to log an exception, and doneLogging when finished.
abstract class Logger {
  void logException(Type t, [String? msg]);
  void doneLogging();
}

void tryFunction(VoidFunction untrustworthy, Logger logger) {
// Invoking this method might cause an exception. Catch and handle
    // them using try-on-catch-finally.
  try {
    untrustworthy();
  } on ExceptionWithMessage catch (e) {
    logger.logException(e.runtimeType, e.message);
  } on Exception {
    logger.logException(Exception);
  } finally {
    logger.doneLogging();
  }
}

참고 사이트1: https://m.blog.naver.com/mingdyuo/221803704762
참고 사이트2: https://dart.dev/codelabs/dart-cheatsheet#initializer-lists

0개의 댓글