2016-04-19 3 views
0

Представьте себе следующий код как часть некоторой программы (Java):Цепной исключения, перехват исключений, чтобы бросить новые

function z(){ 
try{ 
    //some code here, that might throw exceptions. 
}catch (SomeException | SomeOtherException e){ 
    //some exception handling here. 
} 

function y(){ 
    z(); 
} 

function x(){ 
    y(); 
} 

И представьте себе, что функции х и у не будет выполняться как задумано, если исключения SomeException или SomeOtherException выбрасывается внутри функции z. Мы хотим написать наш код таким образом, чтобы функции x и y знали, что Исключения были выбраны функцией z и заставить их действовать соответственно. Каков наилучший способ сделать это?

function z() thrown FunctionZFailedException{ 
    try{ 
    //some code here, that might throw exceptions. 
    }catch (SomeException | SomeOtherException e){ 
    throw new FunctionZFailedException(); 
    } 
} 

function y() throws FunctionYFailedException{ 
    try{ 
    z(); 
    }catch (FunctionZFailedException e){ 
    throw new FunctionYFailedException(); 
    } 
} 

function x(){ 
    try{ 
    y(); 
    }catch (FunctionYFailedException e){ 
    //Do something, like alerting user that something went wrong. 
    } 
} 

Является ли это слишком чрезмерными, что объявляет новые исключения с единственной целью «пересылки» другие исключения на более высокий уровень?

Я думаю, мы могли бы просто позволить SomeException и SomeOtherException взлететь и поймать их внутри функции x. Но imo, который может компенсировать менее читаемый код, например, если исключения, обнаруженные в функции z, являются SQLException и NoSuchAlgorithmException, а функция y является функцией login(). Затем функция x попытается вызвать login() и либо поймать SQLException | NoSuchAlgorithmException, если они позволяют этим исключениям просто взлетать на самый высокий уровень или ловить исключение LoginFailedException, если мы немедленно поймаем каждое исключение и попробуем перебросить новые исключения. Похоже, что catching LoginFailedException делает более удобочитаемый код.

Имо оба пути имеют свои минусы (менее читаемый код и введение многих исключений), и мне интересно, как подобные случаи обычно обрабатываются опытными программистами Java.

Любые общие мысли об исключениях также оценили спасибо, ребята

+0

В большинстве случаев вы хотите включить исходное исключение («причина»): 'catch (FunctionZFailedException e) { throw new FunctionYFailedException (e); } ' – JimmyB

ответ

0

Если вы счастливы с текущим дизайном метода z(), и вы хотите, методы y() и x() «знать», что-то плохое случилось в z(), то вы может иметь z() реконструировать исключение после проглатывания.

public void z() { 
    try { 
     // some code here, that might throw exceptions. 
    } catch (SomeException | SomeOtherException e) { 
     // handle the exception and then rethrow it 
     logger.log("An exception happened in z()."); 
     throw e; 
    } 
} 

public void y() { 
    try { 
     z(); 
    } catch(Exception e) { 
     // handle problem with z() and rethrow the exception 
     logger.log("An exception happened when calling z()."); 
     throw e; 
    } 
} 

public void x() { 
    try { 
     y(); 
    } catch(Exception e) { 
     // handle problem with y() 
     logger.log("An exception happened when calling y()."); 
    } 
} 
1

когда вы смотрите на код (и имена методов и исключения) выяснить, если методы и их брошенные исключения находятся на том же уровне абстракции.

Если у вас есть метод getInputStream(), то соответствующим исключением будет исключение IOException. Если вы вызываете этот метод в вашей getDatabaseConnection(), вы должны поймать IOException и выбросить SQLException. И если вам нужен этот метод для вашего метода saveCustomerToDatabase(), вы должны бросить что-то вроде ProcessFailedException.

Я не большой поклонник написания javadocs, но иногда вы должны спросить себя: смогу ли я написать хороший javadoc для этого метода и его исключения на одном языке (т.е. технический язык, деловой язык и т. Д.)? У вас возникнет проблема с написанием javadoc для метода saveCustomerToDatabase(), если он генерирует исключение IOException.

+0

Я обычно даю -1 для« Я не большой поклонник написания javadocs »... – JimmyB

+0

и я бы не стал жаловаться – EasterBunnyBugSmasher

+0

Поскользнулся на моей мыши, нажал« +1 »сейчас. - Хороший ответ :) – JimmyB

Смежные вопросы