具有不同错误消息的相同异常类型

时间:2017-08-28 14:10:19

标签: java exception exception-handling

我有两种抛出相同异常的方法throws IOException

问题是每个方法从不同的原因抛出它,我包装方法 主要用try catch,推荐的解决方法是什么? 对于每个具有相同类型的异常,我需要不同的消息。

public static void main(String[] args) {

try{

….


readFile(path);

convert(file)

} catch (IOException e) {
    …..
}


private static String readFile(String path) throws IOException {
    //Here files requires IOException -  Reason here cannot Read file
    String lineSeparator = System.getProperty("line.separator");
    List<String> lines = Files.readAllLines(Paths.get(path));
} 


private static String convert(String file) throws IOException {
   //Here reader requires also ioException- Reason here cannot parse file
    ObjectMapper reader = new ObjectMapper(new YAMLFactory());
    Object obj = reader.readValue(file, Object.class);

}

5 个答案:

答案 0 :(得分:4)

有几种方法可以解决这个问题。一种方法,也许是您需要编写的新代码中最重的一种方法,就是从每个辅助方法中抛出一个自定义异常。然后,您可以在单独的块中捕获每个特定的异常。

但我在这里建议的是,您只需将两个调用中的每一个都包含在不同的try-catch块中的辅助方法中:

try {
    readFile(path);
} catch (IOException e) {
    // handle first exception here
}

// more code
try {
    convert(file)
} catch (IOException e) {
    // handle second exception here
}

这很干净,不需要大量重构。如果您遇到此问题,则可以考虑为您的应用程序创建自定义例外。如果您查看了许多Java库,您会发现它们经常使用自己的自定义异常。

如果您想使用自定义异常的路线,可以定义一个,例如

public class FileReadIOException extends Exception {
    public FileReadIOException(String message) {
        super(message);
    }
}

然后使用它:

private static String readFile(String path) throws FileReadIOException {
    try {
        String lineSeparator = System.getProperty("line.separator");
        List<String> lines = Files.readAllLines(Paths.get(path));
    }
    catch (Exception e) {
        throw new FileReadIOException(e.getMessage());
   }
}

try {
    readFile(path);
    // more code
    convert(file)
} catch (FileReadIOException e) {
    // handle first exception here
} catch (SomeOtherException e) {
    // handle second exception here
}

上面显示自定义异常的代码有点人为,因为现实是你的所有代码都在抛出IOException。在您的情况下创建自定义异常并没有增加太多价值,因为它们已经(正当地)抛出IOException。我不确定只处理一种类型的异常是没有意义的。更典型的情况是,如果您正在处理大型企业应用程序,则可以使用自定义异常来处理自定义代码中出错的情况。

答案 1 :(得分:0)

这是我的5美分

    public static void main(String[] args) throws Exception {

    String path = "path";
    String path2 = "path2";


    try{
        readFile(path);
    } catch (IOException e) {
        throw new Exception("read file exception", e);
    }

    try{
        convert(path2);
    } catch (IOException e) {
        throw new Exception("convert exception", e);
    }


}


private static String readFile(String path) throws IOException {
    //Here files requires IOException -  Reason here cannot Read file
    String lineSeparator = System.getProperty("line.separator");
    List<String> lines = Files.readAllLines(Paths.get(path));
}


private static String convert(String file) throws IOException {
    //Here reader requires also ioException- Reason here cannot parse file
    ObjectMapper reader = new ObjectMapper(new YAMLFactory());
    Object obj = reader.readValue(file, Object.class);
}

答案 2 :(得分:0)

我的方法通常是创建自己的异常并将其抛出

public class Snippet {
    public static void main(String[] args) {
        try {
            String path = "";
            readFile(path);
            String file = "";
            convert(file);
        } catch (MyException e) {
            // do whatever
        }
    }

    private static String readFile(String path) throws MyException {
        try {
            String lineSeparator = System.getProperty("line.separator");
            List<String> lines = Files.readAllLines(Paths.get(path));
        } catch (Exception e) {
            throw new MyException("Custom 'readFile' message", e);
        }
    }

    private static String convert(String file) throws MyException {
        try {
            ObjectMapper reader = new ObjectMapper(new YAMLFactory());
            Object obj = reader.readValue(file, Object.class);
        } catch (Exception e) {
            throw new MyException("Custom 'convert' message", e);
        }
    }
}

class MyException extends Exception {
    private static final long serialVersionUID = -3166824380774329449L;

    public MyException(String message, Throwable cause) {
        super(message, cause);
        // TODO Auto-generated constructor stub
    }
}
蒂姆的方式也是有效的。

答案 3 :(得分:0)

@OP解决这个问题的最佳人选就是你自己。 有很多方法可以解决这个问题。检查哪一个更适合你。

根据我的解决方案之一如下。这是基于IOException是许多其他异常的超类的原因。 IOException documentation

try {
     readFile(path);
} catch ( FileNotFoundException e) {
     // handle first exception here
} catch ( EOFException e) {
     // handle 2nd exception here
}

要使上述工作正常,您需要知道抛出了哪种类型的IOException。

另一种解决方案是在您知道可能收到的预期消息时检查各个异常消息。

try {
     readFile(path);
} catch ( IOException e) {
     if(e. getMessage().contains("TXT 1...") {
          //Case handle #1
     } else if(e. getMessage().contains("TXT 2...") {
          //Case handle #2
     }
}

答案 4 :(得分:0)

处理异常的最佳方法是不要使用它们。抛出异常时,表示应用程序的自然生命周期因某种原因而中断。大多数例外都是不言自明的,并为您提供有关事件的准确解释,因此创建新的异常并重新映射那些抛出的异常几乎总是适得其反,并且可能导致更多混乱而不是有用(特别是如果您在团队中工作)。

此外,异常并不需要是终端,在大多数情况下,可以设计场景来重试/提示不同的输入等,以确保生命周期不被中断。在某些情况下杀死异常应用程序可能会产生更多问题(例如:未正确关闭文件,从而丢失处理过的数据)。

现在你的实际问题。如果你有两个或两个以上的组件,那会抛出无关的异常(在这种情况下名称不是关系),最好不要将它们放在同一个try / catch结构中,因为需要更少的解决方法来废弃那个部分,而不是整个事物仍然可以自行退出,或者甚至不需要启动。