2013-04-21 13 views
1

다음과 같은 dowload 함수가 있습니다. 방법에 대한 몇 가지 가능한 예외를 잡아 예외 유형 변수에 저장하고 finally 블록에서 정리 한 후 원 래 예외를 던지려고합니다 (잡힌 사람이있는 경우). 또는 내 자신의 사용자 지정 DownloadFailedException을 throw합니다. . 문제는 내 함수가 예외를 throw한다고 선언하지 않기 때문에 Eclipse가 "처리되지 않은 예외 유형 예외"오류를 발생 시킨다는 것입니다. 이 작업을 수행 할 수있는 "좋은"방법이 있습니까?Java에서 다른 catch 된 예외를 다시 throw합니다.

public static boolean downloadFile(String urlString, String dstPath) throws DownloadFailedException, IOException { 
    if (!Settings.isNetworkAvailable()) { 
     throw new NoNetworkException("Network error: no internet connection. Failed downloading " + urlString); 
    } 
    InputStream input = null; 
    BufferedOutputStream output = null; 
    int fileLength = -1; 
    long total = 0; 
    int statusCode = -1; 
    HttpGet get = new HttpGet(urlString); 
    get.setHeader("User-Agent", Settings.getUserAgent()); 
    get.setHeader("X-My-Id", Settings.getDeviceId()); 
    HttpClient client = new DefaultHttpClient(); 
    HttpResponse response = null; 
    try { 
     response = client.execute(get); 
     statusCode = response.getStatusLine().getStatusCode(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } finally { 
     if (200 != statusCode) { 
      throw new DownloadFailedException("http error: " + statusCode +". Failed downloading " + urlString, statusCode); 
     } 
    } 
    if (null != response) { 
     HttpEntity entity = response.getEntity(); 
     File tmpFile = null; 
     Exception exception = null; 
     try { 
      InputStream is = entity.getContent(); 
      byte b[] = new byte[1]; 
      is.read(b, 0, 0); 
      fileLength = (int)entity.getContentLength(); 
      input = new BufferedInputStream(is, 8192); 
      tmpFile = new File(dstPath + ".tmp"); 
      tmpFile.createNewFile(); 
      output = new BufferedOutputStream(new FileOutputStream(tmpFile), 8192); 

      byte data[] = new byte[8192]; 
      int count; 
      while ((count = input.read(data)) != -1) { 
       total += count; 
       output.write(data, 0, count); 
      } 
     } catch (IllegalStateException e) { 
      exception = e; 
      e.printStackTrace(); 
     } catch (IOException e) { 
      exception = e; 
      e.printStackTrace(); 
     } finally { 
      try { 
       if (null != output) { 
        output.flush(); 
        output.close(); 
       } 
       if (null != input) 
        input.close(); 
      } catch (IOException e) { 
       if (null == exception) 
        exception = e; 
      } 
      if (-1 < fileLength && total != fileLength) { 
       if (null != tmpFile) { 
        tmpFile.delete(); 
       } 
       if (null != exception) { 
// HERE I WOULD LIKE TO RE-THROW THE ORIGINAl EXCEPTION 
        throw exception; // Unhandled exception type Exception 
        //also tried: exception.getClass().cast(exception); 
       } else 
        throw new DownloadFailedException(urlString + ": only " + total + " bytes read out of " + fileLength); 
      } 
      File dstFile = new File(dstPath); 
      tmpFile.renameTo(dstFile); 
     } 
     return true; 
    } 
    return false; 
} 

해결책 : 당신이

if (null != exception) { 
    if (exception instanceof IllegalStateException) 
     throw (IllegalStateException) exception; 
    else if (exception instanceof IOException) 
     throw (IOException) exception; 
    else 
     throw new RuntimeException(message, exception); 
} 
//throw new IOException("Only " + total + "bytes read from " + fileLength); 
throw new DownloadFailedException(message); 

답변

2

:

// HERE I WOULD LIKE TO RE-THROW THE ORIGINAl EXCEPTION 
throw exception; // Unhandled exception type Exception 
// also tried: exception.getClass().cast(exception); 

나는 이것을 사용합니다 :

if(exception instanceof IOException) 
    throw (IOException) exception; 
else 
    throw new DownloadException(exception); 

당신이 describ 상황을 바탕으로 코드의 끝에서 throws 절을 사용하면 해당 코드가 원하는 작업을 수행합니다. 영어로, 여기에 코드가하는 작업은 다음과 같습니다

  • 당신이 Exception을 잡아 그것이 IOException의 경우에, 당신이 던져 싶어, 당신은 당신이 Exception을 잡을 경우 IOException
  • 을 던져 원하고 그것이 IOException 아니다 a DownloadException (자신 만의 작품). IOExceptionDownloadException에 랩핑하여 구현시 메서드의 throws 절과 일치하도록합니다. 당신이 Exception를 잡을 수없는 경우
  • 는, 당신은 인생이 당신이 서명 생성자하지 않는 경우 (클래스 DownloadExceptionpublic DownloadException(Throwable e){super(e);} 같은 생성자를 추가해야 할 수 있습니다

주를 정상적으로 계속하려면 이미 존재 함)이 컴파일되기 전에.

+1

RuntimeException이기 때문에 "else if (exception instanceof IllegalStateException) .."을 추가해야 할 필요가 있지만 시도해 보겠습니다. (확인되지 ​​않았으므로 함수의 throws 선언에없는 것입니다) – Gavriel

+0

그건 의미가 있습니다. 죄송합니다. 위에서 선택하지 않았습니다. 'IllegalArgumentException'을 테스트하는 것보다는'RuntimeException'을 테스트하고 일치하는 것을 던져 버릴 수도 있습니다 ('RuntimeException'에 캐스트). – sigpwned