2016-11-23 1 views
2

나는 응용 프로그램의 흐름을 지시하는 데 예외를 사용해서는 안되며 예외적 인 경우 (예 : 데이터베이스에 연결하지 못한 경우) 안정된 상태로 응용 프로그램을 복구해야한다고 읽었습니다. .예외 - "예외적 인"것은 무엇입니까?

예외가 사용되어서는 안되는 예로는 잘못된 로그인을 제공하는 사용자가 있습니다. 그렇게 될 것으로 예상되기 때문에 예외는 아닙니다.

나는 다음과 같은 경우는 예외인지 아닌지 확실하지 않다 :

나는 현재 간단한 블로그를 디자인하고있다. "게시물"은 하나의 "카테고리"에 할당됩니다. 내 게시물 테이블에서 외래 키 제약 조건이있는 category_id 필드가 있습니다.

현재 Laravel을 사용하고 있으므로 현재 게시물이있는 범주를 삭제하려고하면 외래 키 제약 조건 때문에 \ Illuminate \ Database \ QueryException이 발생합니다. 나는 내 블로그가 작동하는 방법을 알고 있기 때문에 내가 사용한다

try { 
    $category->delete(); 
} 
catch (\Illuminate\Database\QueryException $e) { 
    // Tell the user that they can't delete the category because there are posts assigned to it 
} 

나 :

if ($category->posts->isEmpty()) { 
    $category->delete(); 
} 
else { 
    // Tell the user they can't delete... 
} 

어떤 조언을 주시면 감사하겠습니다 그러므로 나는이에 의존와 같은 코드를 작성해야한다. 감사!

+2

나는이 주로 의견을 기반으로 생각하지, 하지만 두 번째 옵션으로 갈 것입니다. 왜? 1. 규칙이 명확합니다. 2. 다른 종류의 데이터베이스 예외가 오도 된 오류를주지 않도록하십시오. 3. 누군가가 계단식 삭제 기능을 켜면 논리는 여전히 동일하게 작동합니다. –

+1

@ DarkFalcon의 대답을 계속하면 예외를 던지는 것이 무거워 지므로 일어날 일을 제외하고는 사용하지 말아야합니다. –

답변

1

매우 의견을 바탕으로 작성되었습니다. 내 의견을 알려 드리겠습니다 : 많은 정보를 첨부 할 수 있기 때문에 예외가 발생합니다. 메소드의 필요없이 "콜 스택 (callstack)"을 보낼 수 있습니다 모든 호출의 반환 값을 확인하고 자신의 호출자에게 무엇이든 반환합니다.

이렇게하면 호출 스택의 원하는 레이어에서 오류를 쉽게 처리 할 수 ​​있습니다.

메서드가 반환해야하는 것은 이고 결과는입니다 (void 인 경우에도 마찬가지입니다). 어떤 이유로 든 호출에 실패하면 이 아니며 반환 값이 있어야합니다.

오류는 반환 값으로 전송하면 안되지만 예외가 있습니다.

db-queries를 수행하는 함수를 상상해보십시오. KeyAlreadyExistsException, InvalidSyntaxExceptionNullPointerException - 대부분이 코드의 다른 부분에서이 "오류"를 처리하려고합니다.

예 하나, 쉽게 "처리"(하나는 코드 오류입니다, 하나는 쿼리 오류가 하나의 논리적 오류입니다) :

try{ 
    method1(1); 
}catch (Exception $e){ 
    //Handle all but NullpointerExceptions here. 
} 
--- 
method1($s){ 
    try{ 
    method2($s+2); 
    } catch (NullPointerException $e){ 
    //only deal with NPEs here, others bubble up the call stack. 
    } 
} 
--- 
method2($s){ 
    //Some Exception here. 
} 

예 두 사람은 - 당신은 볼 필요한 "중첩"및 스택 깊이는 여기에서 2입니다.

$result = method1(1); 
if ($result === 1){ 
    //all good 
}else{ 
    //Handle all but NullpointerExceptions here. 
} 
--- 
method1($s){ 
    $result = method2($s+2); 
    if ($result === 1){ 
    return $result; 
    }else{ 
    if ($result === "NullPointerException"){ 
     //do something 
    } 
} 

method2($s){ 
    //Exception here. 
} 

는 특히 유지 관리 -에 대한 예외는 큰 장점을 가지고 : 당신이 새로운 "예외"를 추가하는 경우 - worstcase은 처리되지 않은 예외 수 있지만 코드 실행이 중단됩니다.

당신이, 당신이 모든 발신자가 새로운 오류를 인식 것을 확인해야 새로운 추가 "오류를 반환"경우 : 이제 모두의 취급을 고려

function getUsername($id){ 
    // -1 = id not found 
    $name = doQuery(...); 
    if (id not found) return -1; 
    else return $name; 
} 

function getUsername($id){ 
    $name = doQuery(...); 
    if (id not found) throw new IdNotFoundException(...); 
    return $name; 
} 

대 경우 :

if (getUsername(4)=== -1) { //error } else { //use it } 

try{ 
    $name = getUsername(4); 
    //use it 
}catch (IdNotFoundException $e){ 
    //error 
} 

이제 리턴 코드 -2을 추가하십시오. 오류 코드가 구현 될 때까지 첫 번째 방법은 사용자 이름이 -2 인 것으로 가정합니다. 두 번째 방법 (Another Exception)은 호출 스택에서 처리되지 않은 예외를 사용하여 실행이 중지되도록합니다.

오류 운송을위한 반환 값 (모든 종류의) 처리는 오류가 발생하기 쉽고 오류가 어딘가에서 사라져 "잘못된"해석 결과로 바뀔 수 있습니다. 예외를 사용

는 안전 : 당신이 중 하나가 사용하는 반환 값을 가지고, 또는 (처리되거나 처리되지 않은) 예외지만, 등으로 인해 autocasts에는 "잘못된 값은"

관련 문제