简体   繁体   English

抛出Java中不同的捕获异常

[英]Rethrow different caught exceptions in java

I have the following dowload function. 我有以下下载功能。 I catch some possible exceptions on the way, and store them in an Exception type variable, and after cleaning up in the finally block, I would like to re-throw the original exception (if there was one caught) or throw my own custom DownloadFailedException. 我在路上捕获了一些可能的异常,并将它们存储在Exception类型的变量中,并在finally块中进行清理后,我想重新抛出原始异常(如果捕获到一个异常)或抛出我自己的自定义DownloadFailedException 。 The problem is that Eclipse gives me "Unhandled exception type Exception" error, because my function doesn't declare throws Exception. 问题在于Eclipse给了我“未处理的异常类型异常”错误,因为我的函数没有声明抛出异常。 Is there a "nice" way to do this? 有没有一种“不错”的方式来做到这一点?

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;
}

SOLUTION: 解:

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);

Where you have: 您在哪里:

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

I would use this: 我会用这个:

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

Based on the situation you described and the throws clause at the end of your method, that code does what you want to do. 根据您描述的情况和方法末尾的throws子句,该代码可以完成您想要的操作。 In English, here's what that code does: 用英语,这是该代码的作用:

  • If you catch an Exception and it's an IOException , then you want to throw an IOException 如果您捕获到一个Exception且它是一个IOException ,那么您想抛出一个IOException
  • If you catch an Exception and it's not an IOException , you want to throw a DownloadException (of your own creation). 如果捕获到一个Exception而不是IOExceptionIOException抛出一个DownloadException (由您自己创建)。 We wrap any non- IOException in a DownloadException so that your implementation is consistent with the throws clause on your method. 我们将任何非IOException包装在DownloadException以使您的实现与方法上的throws子句一致。
  • If you do not catch an Exception , then you want life to continue as normal 如果您没有捕获Exception ,那么您希望生活继续正常进行

Note that you may need to add a constructor like public DownloadException(Throwable e){super(e);} to your class DownloadException (if a constructor with that signature doesn't already exist) before this will compile. 请注意,您可能需要添加一个构造像public DownloadException(Throwable e){super(e);}到你的类DownloadException (如果与签名的构造函数不存在),在此之前将编译。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM