prosource

의 일반적인 프로그래밍 오류입니다.예외를 처리할 때 네트?

probook 2023. 5. 18. 21:08
반응형

의 일반적인 프로그래밍 오류입니다.예외를 처리할 때 네트?

예외를 처리할 때 가장 자주 범하는 실수는 무엇입니까?

예외 처리는 에서 "올바른" 방법을 배우는 것이 가장 어려운 일 중 하나일 수 있습니다.넷. 특히 .NET 개발자들이 피해야 할 공통 프로그래밍 실수에 대한 현재 1위 답변을 고려한다면?예외 처리와 관련이 있습니다.

가장 일반적인 실수를 나열함으로써 우리 모두가 예외를 더 잘 처리하는 법을 배울 수 있기를 바랍니다.

예외를 처리할 때 가장 자주 범하는 실수는 무엇입니까?

생각나는 게 많아요.

먼저 예외를 성가신 것, 완고한 것, 치명적인 것, 외생적인 것으로 분류하는 것에 대한 제 기사를 읽으십시오.

http://ericlippert.com/2008/09/10/vexing-exceptions/

몇 가지 일반적인 오류:

  • 외부에서 발생한 예외를 처리하지 못했습니다.
  • 성가신 예외를 처리하지 못했습니다.
  • 성가신 예외를 발생시키는 방법의 구성.
  • 치명적인 예외와 같이 실제로 처리할 수 없는 예외를 처리합니다.
  • 코드에서 버그를 숨기는 예외 처리. 완고한 예외를 처리하지 말고 버그를 수정하여 버그가 처음부터 발생하지 않도록 합니다.

  • 보안 오류: 안전하지 않은 모드로 전환하지 못했습니다.

    try
    {
      result = CheckPassword();
      if (result == BadPassword) throw BadPasswordException();
    }
    catch(BadPasswordException ex) { ReportError(ex); return; }
    catch(Exception ex) { LogException(ex); }
    AccessUserData();
    

    무슨 일이 있었는지 보세요?안전하지 않은 모드에 실패했습니다.CheckPassword가 NetworkDriverIsAllMessedUpException을 던진 경우 암호가 올바른지 여부에 관계없이 이를 포착하고 기록한 다음 사용자의 데이터에 액세스했습니다.안전 모드에 실패합니다. 예외가 발생하면 최악의 경우를 가정합니다.

  • 보안 오류: 중요한 정보를 직간접적으로 유출하는 예외를 생성합니다.

    이것은 정확히 코드의 예외를 처리하는 것에 관한 것이 아니라 적대적 코드에 의해 처리되는 예외를 생성하는 것에 관한 것입니다.

    재밌는 얘기..NET 1.0이 고객에게 제공되기 전에 "이 메서드를 호출한 어셈블리는 C:\foo.txt 파일의 이름을 결정할 권한이 없습니다."라는 예외를 발생시키는 메서드를 호출할 수 있는 버그를 발견했습니다.좋습니다. 알려주셔서 감사합니다.해당 어셈블리가 예외를 탐지하고 해당 메시지를 조회하여 파일 이름을 가져오는 것을 막는 것은 무엇입니까?아무 것도 없어요.우리는 그것을 선적하기 전에 고쳤습니다.

    그것은 직접적인 문제입니다.는 제가 접적인문제구문것다입니에서 입니다.LoadPictureVBScript로.잘못된 인수가 디렉터리인지, 사진이 아닌 파일인지, 존재하지 않는 파일인지에 따라 다른 오류 메시지를 표시했습니다.매우 할 수 있다는 것을 합니다!", 매우느린사용수있습다니할즉로저!다양한 작업을 시도함으로써 다른 사용자의 하드 디스크에 어떤 파일과 디렉터리가 있는지에 대한 그림을 점차 구축할 수 있습니다.예외는 신뢰할 수 없는 코드에 의해 처리되는 경우 해당 코드가 예외를 발생시키기 위해 수행한 작업에서 사용자의 개인 정보를 전혀 학습하지 않도록 설계되어야 합니다.(LoadPicture는 이제 훨씬 덜 유용한 오류 메시지를 제공합니다.)

  • 보안 및 리소스 관리 오류: 리소스를 정리하지 않는 처리기는 리소스 누출이 발생하기를 기다리고 있습니다.리소스 누출은 악의적인 부분 신뢰 코드에 의해 서비스 거부 공격으로 사용될 수 있으며, 이는 의도적으로 예외를 생성하는 상황을 만듭니다.

  • 견고성 오류: 처리기는 특정 외부 예외를 처리하지 않는 한 프로그램 상태가 엉망이라고 가정해야 합니다.이는 특히 최종 블록에 해당합니다.예기치 않은 예외를 처리할 때 프로그램에서 무언가가 심각하게 잘못되었을 가능성이 완전히 있습니다.작동 중인 하위 시스템이 있는지, 작동 중이면 호출이 상황을 더 좋게 만들 것인지 아니면 더 나쁘게 만들 것인지 알 수 없습니다.오류를 기록하고 가능하면 사용자 데이터를 저장하는 데 집중하고 최대한 깨끗하게 종료합니다.어떤 것도 제대로 작동하지 않는다고 가정합니다.

  • 보안 오류: 보안에 영향을 미치는 일시적인 글로벌 상태 돌연변이는 적대적일 수 있는 코드가 실행되기 전에 실행 취소되어야 합니다.적대적 코드는 블록이 실행되기 전에 실행될 수 있습니다!자세한 내용은 이에 대한 내 기사를 참조하십시오.

http://blogs.msdn.com/ericlippert/archive/2004/09/01/224064.aspx

다음과 같은 예외 다시 던지기:

try 
{ 
   // some code here
}
catch(Exception ex)
{
   // logging, etc
   throw ex;
}

이렇게 하면 스택 추적이 사라지므로 사용이 훨씬 줄어듭니다.올바른 폐기 방법은 다음과 같습니다.

try 
{ 
   // some code here
}
catch(Exception ex)
{
   // logging, etc
   throw;
}

대부분의 경우 특정 예외를 포착해야 할 때 모든 예외 포착:

try {
  // Do something.
} catch (Exception exc) {
  // Do something.
}

다음보다는:

try {
  // Do something.
} catch (IOException exc) {
  // Do something.
}

예외는 가장 구체적인 순서에서 가장 작은 순서로 정렬해야 합니다.

의미 없는 메시지가 포함된 예외를 다시 작성합니다.

try
{
    ...
}
catch (Exception ex)
{
   throw new Exception("An error ocurred when saving database changes").
}

운영 환경에서 이와 같은 코드가 실행되는 것을 얼마나 자주 볼 수 있는지 믿지 못할 것입니다.

아무도 이런 빈 캐치 블록을 보는 것에 대해 이야기하지 않습니다.

 try{  
      //do something
    }
catch(SQLException sqex){  
        // do nothing  
    }

또한 대체 메서드 흐름을 만드는 데 예외 처리를 사용하지 마십시오...

 try{  
     //do something  

 }catch(SQLException sqex){  

     //do something else  
 }

개체에 사용 안 함:

File myFile = File.Open("some file");
callSomeMethodWhichThrowsException(myFile);
myFile.Close();

. 가 finalizer 앞에 때문입니다. myFile은 myFile의 finalizer가 호출되지 않습니다.myFile.Close()호출되었습니다.

이를 위한 적절한 방법은

using(File myFile = File.Open("some file"))
{
    callSomeMethodWhichThrowsException(myFile);
}

이것은 컴파일러에 의해 다음과 같은 것으로 번역됩니다.

File myFile = File.Open("some file");
try
{
    callSomeMethodWhichThrowsException(myFile);
}
finally
{
    if(myFile != null)
        myFile.Dispose(); //Dispose() calls Close()
}

그래서 파일은 예외가 있더라도 닫힙니다.

캡처된 예외를 다시 던질 때 내부 예외를 설정하는 것을 잊음

try
{
    ...
}
catch (IOException ioException)
{
    throw new AppSpecificException("It was not possible to save exportation file.")
    // instead of
    throw new AppSpecificException("It was not possible to save exportation file.", ioException);
}

제가 이 답변을 게시할 때 보안상의 이유로 내부 예외를 포함할지 여부를 항상 고려해야 한다는 점을 언급하는 것을 잊었습니다.Eric Lippert가 이 항목에 대한 다른 답변에서 지적했듯이 일부 예외는 서버의 구현 세부사항에 대한 중요한 정보를 제공할 수 있습니다.따라서 예외를 처리할 호출자를 신뢰할 수 없는 경우 내부 예외 정보를 포함하는 것은 좋지 않습니다.

빈 캐치:

//What's the point?
catch()
{}

다시 던지기:

//Exceptions are for *adding* detail up the stack
catch (Exception ex)
{throw ex;}

많은 시나리오를 다루는 예외를 가정하는 것은 구체적인 것이었습니다.실제 시나리오는 예외 처리가 항상 모든 오류를 세션 타임아웃으로 가정하고 모든 오류를 기록하고 세션 타임아웃으로 보고하는 웹 앱이었습니다.

다른 예:

try
{
     Insert(data);
}
catch (SqlException e)
{
   //oh this is a duplicate row, lets change to update
   Update(data);
}

예외를 기록합니다.예외 대신 메시지를 입력합니다.문자열로()

ToString 메서드의 반환을 기록해야 하는 동안 코드 로깅 예외 메시지만 표시되는 경우가 많습니다.ToString은 메시지보다 예외에 대한 훨씬 더 많은 정보를 제공합니다.메시지 외에도 내부 예외 및 스택 추적과 같은 정보가 포함됩니다.

Out Of Memory를 잡으려고 합니다.예외 또는 스택 오버플로예외 - 런타임이 종료되어 동일한 프로세스 내에서(또는 CLR 전체에서) 이를 잡을 수 있는 방법이 있습니다.

메모리 부족예외:메모리가 부족하여 프로그램 실행을 계속할 수 없을 때 발생하는 예외입니다.

".NET Framework 버전 2.0부터 스택 오버플로가 발생했습니다.예외 개체는 시도-캐치 블록에 의해 탐지될 수 없으며 해당 프로세스는 기본적으로 종료됩니다.따라서 사용자는 스택 오버플로를 감지하고 방지하기 위해 코드를 작성해야 합니다."

탐지 처리기 내에서 가능한 예외를 탐지하지 못했습니다.이로 인해 잘못된 예외가 위쪽으로 전파될 수 있습니다.

예:

try
{
    DoImportantWork();
}
catch
{
    Cleanup();        
    throw;
}

그러면 어떻게 됩니까?Cleanup()예외를 설정하시겠습니까?이 캐치 핸들러에서 정리() 메서드를 가리키는 예외를 보고 싶지 않습니다.당신은 원래의 오류를 원합니다.정리 오류를 기록할 수 있지만 로그 코드에서도 예외를 발생시키지 않도록 예외 처리가 필요합니다.

try
{
    DoImportantWork();
}
catch
{
    try
    {
        Cleanup();        
    }
    catch
    {
        // We did our best to clean up, and even that failed.
        // If you try to log this error, the logging may throw yet another Exception.
    }
    throw;
}

틀렸어

try
{
   // Do something stupid
}
catch
{
   // ignore the resulting error because I'm lazy, and later spend
   // a week trying to figure out why my app is crashing all over
   // the place.
}

낫다.

try
{
    /// do something silly.
}
catch (InvalidOperationException ex)
{
    /// respond, or log it.
}
catch (Exception e)
{
    /// log it.
}

정상적인 흐름 제어에 대한 예외 사용.예외는 예외여야 합니다.양호한 작업/예상 작업인 경우 반환 값 등을 사용합니다.

언급URL : https://stackoverflow.com/questions/2883936/common-programming-mistakes-in-net-when-handling-exceptions

반응형