IT박스

데이터 유효성을 검사 할 때 예외를 던지는 것이 좋은 생각입니까, 나쁜 생각입니까?

itboxs 2020. 11. 30. 07:57
반응형

데이터 유효성을 검사 할 때 예외를 던지는 것이 좋은 생각입니까, 나쁜 생각입니까?


데이터의 유효성을 검사 할 때 다음을 수행하는 습관이 생겼습니다.

참고 : 실제로 각 검사에 대한 개별 부울이 없습니다. 이것은 단지 예입니다.

또 다른 참고 사항 : 테스트 중 오류 처리가 제대로 수행됩니다. try-catch에서 throw되는 유일한 예외는 내 것입니다.

try {
  if (validCheckOne = false) {
    throw new Exception("Check one is bad");
  }
  if (validCheckTwo = false) {
    throw new Exception("Failed because of check2");
  }
  if(validCheckTen = false) {
    throw new Exception("Yet another failure on your part: check10.");
  }
} catch(Exception e) {
  MessageBox.Show("Your stupid data is wrong! See for yourself: " + e.Message);
}

이것은 나쁜 습관입니까? 예외를 던지면 프로그램의 실행이 느려지거나 권장되지 않습니까?


개인적으로 저는 비즈니스 규칙 유효성 검사를 위해 예외를 던지는 것을 좋아합니다 (사용자 입력 유효성 검사에는 그다지 많지 않음). 문제가 업스트림으로 처리되도록하기 때문입니다. 내 비즈니스 개체가 일종의 유효성 검사 결과를 반환하면 호출자가 무시할 수 있습니다. 원한다면 카우보이라고 불러주세요 :)

여기에있는 모든 사람들은 "예외는 예외적 인 상황을위한 것입니다"라는 말을 반복하고 있지만, 그것은 예외적 인 상황에 그들을 사용하는 것이 왜 나쁜지 이해하지 못합니다. 그 이상이 필요합니다. 예외 발생으로 인한 성능 저하가 정말 그렇게 나쁜가요? 사용 가능한 벤치 마크가 있습니까?


나는 여기서 만트라를 반복 할 것이다. 예외를 던지는 것은 예외적 인 상황에서 이루어져야한다. 잘못 입력 된 데이터는 실제로 예외가 아닙니다.


나는 MusiGenesis의 대답을지지합니다.

또한 ...


성능 예외를 던지는 천 지침입니다. 최종 사용자 시간에 비하면 아무것도 아니지만 내부 코드에서는 느립니다.

또 다른 문제는 예외를 사용하면 유효성 검사가 첫 번째 실패를보고하는 것으로 제한된다는 것입니다 (다음 실패를 찾으려면 다음에 모두 다시 수행해야 함).


"예외는 예외적 인 상황을위한 것"이라는 자주 반복되는 진술에 추가하여, 내가 좋아하게 된 추가로 명확한 규칙이 있습니다.

사용자가 원인이 되었다면 예외는 아닙니다.

예외는 모든 사용자가 이상한 일을하기 때문에 사용자가 이상한 일을하는 것이 아니라 시스템 측 일 (서버가 다운되고 리소스를 사용할 수 없음)에 대한 것입니다.


제목에서는 "유효성 검사"데이터라고합니다. 이는 여러 수준에서 발생할 수 있습니다. 사용자가 입력 한 데이터를 확인하는 GUI (근처)에서 오류를 예상하고 오류를 다시보고 할 수있는 방법이 있어야합니다. 이 경우 예외는 부적절합니다.

그러나 데이터 유효성 검사는 비즈니스 규칙 클래스 간의 다른 경계에서도 발생할 수 있습니다. 거기에서 데이터의 오류는 흔하지 않고 예기치 않은 오류입니다. 발견하면 던져야합니다.


데이터가있을 것으로 예상하고 데이터가없는 것이 예상치 못한 경우 예외를 던지는 것이 좋습니다. 예외를 던지는 것은 매우 비싸지 만 (느리지 만) 예기치 않은 상황을 처리하는 가장 좋은 방법입니다.


따라서 일부 언어에서는 예외 발생 및 잡기가 "비용이 많이 들지만"다른 언어에서는 예외 발생 및 잡기가 정확히 요구됩니다.

예를 들어 스몰 토크에서는 다 계층 예외 포착 솔루션을 빠르게 구축 할 수 있습니다. 유효성 검사 패스는 특정 입력 데이터 세트에 잘못된 모든 것을 나타내는 예외를 수집 할 수 있습니다. 그런 다음 입력에 문제가있는 모든 것에 대해 사람이 읽을 수있는 설명을 형식화하는 책임이있는 상위 수준의 포수에게 모두를 던집니다. 차례로 형식화 된 설명과 함께 체인 위쪽에 단일 예외가 발생합니다.

그래서 ... 내 말은 예외는 예외 처리 아키텍처가 예외 처리 아키텍처를 지원하지 않고 합리적인 작업을 수행하는 경우에만 발생하는 것이 좋지 않으며 포수가 할 모든 일은 EXIT 또는 do 똑같이 부적절한 것.


이것은 나쁜 행동입니다. 예외 조건 예외 입니다. 스택 등을 생성하기 위해 리소스를 사용합니다. 예외는 프로세스 흐름을 지시하는 데 사용되어서는 안됩니다.


일반적으로 예외를 사용하여 조건부 흐름을 구현하는 것은 바람직하지 않습니다. 이런 식으로하는 것이 낫습니다

  error = false;
  while(true) {
    if(validCheckOne == false) { 
       msg = "Check one is bad"; 
       error = true;
       break;
    }

    if(validCheckTwo == false) { 
       msg = "Check two is bad"; 
       error = true;
       break;
    }
    ...
    break;
  }
  if (error) {
     ..
  }

아무것도 할 수없는 상황이 발생하면 예외를 던져야합니다. 상위 계층의 소프트웨어는 예외를 포착하고 이에 대해 조치를 취할 수있는 기회를 갖게 될 것입니다.


나는 일반적으로 "예외는 예외적이어야한다"라는 규칙에 동의하지만, 파이썬에 대해 예외 (ha!)를 만들 수 있습니다. 여기서는 흐름을 제어하는 ​​것을 제외하고 try ...를 사용하는 것이 효율적이고 좋은 관행으로 간주 될 수 있습니다.

를 들어 다른 용도로 예외 사용을 참조하십시오 .


질문에 설명 된대로 예외를 사용하는 것이 일반적으로 최선의 생각이 아닌 잘못된 것이라고 제안합니다 . 나는 더 나아가서 예외를 던지는 유효성 검사 가 최선의 방법이 아니라고 말할 것입니다 . 대신 부울을 반환하고 액세스 할 수있는 유효성 검사 오류 메시지 목록을 저장합니다. 동반 저장 메소드는 유효하지 않은 객체에서 호출되는 경우 예외를 발생시킬 수 있습니다.

따라서 유효성 검사가 실패하면 유효성 검사 오류 메시지가 사용자에게 표시 될 수 있습니다 (기록되거나 반환 됨). 유효성 검사가 통과되면 save를 호출 할 수 있습니다. 유효하지 않은 객체에 대해 save를 호출하면 적절한 예외가 발생합니다.

예제 코드의 또 다른 잠재적 인 문제는 (물론 요구 사항에 따라 다름) 발생하는 첫 번째 유효성 검사 오류 만 발생한다는 것입니다. 사용자 POV에서 이것을 상상해보십시오.

  • 저장을 클릭하십시오.
  • 오류 메시지 받기
  • 오류 수정
  • 다시 저장을 클릭하십시오.
  • 다른 오류 메시지를받습니다. 성가신.

사용자로서 모든 유효성 검사 오류를 한 번에 반환하여 다시 시도하기 전에 모두 수정할 수 있기를 원합니다.


데이터 유효성 검사가 타이트한 루프에있는 경우에만 중요합니다. 대부분의 경우 코드에서 일관성이 있는 한 무엇을 선택하든 상관 없습니다 .

위의 샘플과 유사한 코드가 많은 경우 던질 도우미 메서드를 도입하여 정리할 수 있습니다.

private void throwIf( bool condition, String message )
{
    if( condition )
        throw new ApplicationException( message );
}

(또한 이렇게하면 "validCheckOne = false"대 "validCheckOne == false"와 같은 오류를 파악하는 데 도움이됩니다. :)


이 질문은 주로 답변 때문에 여전히 흥미 롭습니다.

예외에 관해서는 많은 논쟁이 있습니다. 성능에서 예외 철학에 이르기까지 우리가 원하는 모든 방향으로 포인트를 방어 할 수 있습니다. 그리고 그들은 모두 나에게 옳게 들립니다.

그러나 때때로 우리는 방향을 고수해야합니다. 이 경우 유효성 검사 자체라고 생각합니다.

무언가를 검증하고 싶을 때 매개 변수가 유효하지 않을 때 무엇이 ​​잘못되었는지 (기록하거나 사용자에게 보여주기 위해) 알고 싶습니다. 사용자 입력 유효성 검사와 혼합 된 비즈니스 유효성 검사와 같은 유효성 검사 계층이 있다고 생각했습니다.

For instance, when dealing with user input, a lot of weird cases can happen. A pasted data from a website full of hidden char (\t \n etc), typos, and a really huge kinds of cases that a specific exception could allow further analysis or message to the uses much more precisely than a simple "false" return.


Well, i know it's an old question. But i'll let my opinion here for the googler's who falled here like me:

  1. If you are using a language with a bad try/catch support AVOID THROWING exceptions for data validation;
  2. DO NOT THROW a exception that will not be handled by the caller or alserwhere;
  3. DO NOT THROW a exception if you need to validate the rest of the received data;
  4. You can THROW a exception in cases where the code block cannot continue without the invalid data; And if you do not interrupt the process you can get a unhandled exception;

An example:

/*
 * Here it's a common problem i have: Someone pass a list of products i need to
 * retrieve from the database and update some information;
 */

//This is a class to represent the product
function Product(id, name, price) {
	this.id = id;
	this.name = name;
	this.price = price;
}

//This is an example function to retrieve the product from the database
function findProductInDatabase(productId) {

	//If the product exists on the database, the function will return it
	if (productId == 12) {
		var product = new Product(12, "Book", 20.5);
		return product;
	}
	
	//If the product do not exists, it will return null
	return null;
}

//This is a function that will receive the productID and will update the received parameters
function updateProduct(productId, newProductName, newProductPrice) {

	var productFromDatabase = null;
	var errorMessage = "";
	
	//Retrieve the product
	productFromDatabase = findProductInDatabase(productId);

	//If the product do not exist, i need to interrupt de method imediatily and alert the caller
	if (!productFromDatabase) {
		throw "Product not found";
	}
	
	//Validate the other parameters, but in this case	i can validate all the parameters
	if (newProductPrice < 10) {
		errorMessage += "the price is too low";
	}
	
	if (newProductName.includes("<")) {
		
		//If already has a error message in the variable i append " and " to the message make sense
		if (errorMessage) {
			errorMessage += " and ";
		}
		
		errorMessage += "the new name has invalid characters";
	}
	
	if (errorMessage) {
		//if theres any error, i will throw a exception with the messages
		throw errorMessage;
	}
}

//This parte is where the method id called;
try {
	updateProduct(9, "Book", 10.5);
} catch (exception) {
	console.log("Case 1: " + exception);
}
try {
	updateProduct(12, "<Book", 9);
} catch (exception) {
	console.log("Case 2: " + exception);
}

참고URL : https://stackoverflow.com/questions/1504302/is-it-a-good-or-bad-idea-throwing-exceptions-when-validating-data

반응형