Должен ли я генерировать исключения в блоке if-else? - PullRequest
0 голосов
/ 27 декабря 2018

Вот код:

public Response getABC(Request request) throws Exception {
    Response res = new Response();
    try {
        if (request.someProperty == 1) {
            // business logic
        } else {
           throw new Exception("xxxx");
        }
    } catch (Exception e) {
        res.setMessage(e.getMessage); // I think this is weird
    }
    return res;
}

Эта программа работает нормально.Я думаю, что это должно быть переработано, но как?

Ответы [ 8 ]

0 голосов
/ 09 января 2019

То же самое, если вы хотите получить конкретное сообщение об исключении, возвращаемое JVM при сбое, тогда вы можете использовать try-catch с методами getMessage () или printStackTrace () в блоке catch.Так что здесь вы можете изменить свой код как:

public Response getABC(Request request) throws Exception {
    Response res = new Response();
    try {
        if (request.someProperty == 1) {
            // business logic
        } 
    } catch (Exception e) {
        res.setMessage(e.getMessage); 
    }
    return res;
}
0 голосов
/ 27 декабря 2018

Механизм исключения имеет три цели:

  1. Немедленно отключить нормальный поток программ и возвращаться вверх по стеку вызовов, пока не будет найден подходящий перехватчик.
  2. Предоставить контекст в форметипа исключения, сообщения и, необязательно, дополнительных полей, которые код блока перехвата может использовать для определения курса действий.
  3. Трассировка стека для программистов, чтобы они могли проводить криминалистический анализ.(Раньше это было очень дорого делать).

Это большой функционал для механизма.Чтобы сохранить программы настолько простыми, насколько мы можем - для будущих сопровождающих - поэтому мы должны использовать этот механизм только в том случае, если нам действительно придется.

В вашем примере кода я ожидал бы любой throw заявление о том, что это очень серьезная вещь, указывающая на то, что что-то не так, и ожидается, что код где-то справится с этой чрезвычайной ситуацией.Мне нужно понять, что пошло не так и насколько это серьезно, прежде чем читать остальную часть программы.Здесь это просто фантастическое возвращение Струны, и я почесал голову и подумал: «Зачем это было нужно?»и эти дополнительные усилия могли бы быть потрачены лучше.

Так что этот код не так хорош, как может быть, но я бы изменил его, только если бы у вас было время провести полный тест.Изменение потока программы может привести к незначительным ошибкам, и вам нужно иметь в виду эти изменения, если вам нужно что-то исправить.

0 голосов
/ 27 декабря 2018

Я думаю, вы можете упустить смысл этой попытки / улова.Код использует систему исключений, чтобы сообщать вызывающему абоненту любое сообщение об исключении.Это может быть глубоко во вложенном стеке вызовов, а не только в «бросках», которые вы смотрите.

Другими словами, объявление «бросков» в вашем примере кода использует преимущества этого механизма для доставкисообщение клиенту, но оно почти наверняка не является основным предполагаемым пользователем try / catch.(Также это неаккуратный, довольно дешевый способ доставки этого сообщения - это может привести к путанице)

Это возвращаемое значение в любом случае не является хорошей идеей, потому что исключения часто не имеют сообщений и могут быть повторно отправлены.завернутый ... это лучше, чем ничегоСообщения об исключениях просто не лучший инструмент для этого, но обработка исключения на высоком уровне, как это, все еще хорошая идея.

Моя точка зрения заключается в том, что если вы реорганизуете этот код, то обязательно ищите исключения во время выполнениякоторые могут быть выброшены в любом месте вашей кодовой базы (по крайней мере, в любое место, вызываемое во время обработки сообщения) - и даже в этом случае вам, вероятно, следует сохранить сообщение перехвата / возврата как универсальное средство на случай, если возникнет исключение времени выполнения, которого вы не сделалиожидать.Вам не нужно возвращать ошибку «Сообщение» как сообщение вашего ответа - вместо этого может быть какое-то быстрое «Мы не можем обработать ваш запрос в это время», но обязательно выгрузите трассировку стека в журнал,Вы в настоящее время выбрасываете его.

0 голосов
/ 27 декабря 2018

Почему вы использовали оператор try / catch, когда вы уже выбросили Проверенное исключение ?

Проверенное исключение обычно используется в некоторых языках, таких как C ++ или Java, ноне на новом языке, как Котлин.Я лично ограничиваю его использование.

Например, у меня есть такой класс:

class ApiService{
    Response getSomething() throw Exception(); 
} 

, который выглядит чистым и читаемым, но подрывает полезность механизма обработки исключений.Практически, getSomething() не вызывает выбрасывание проверенного исключения, но все равно нужно вести себя как оно?Это работает, когда есть кто-то выше ApiService, который знает, как справиться с непредсказуемыми или непредсказуемыми ошибками вроде этой.И если вы действительно можете знать, как с этим справиться, тогда используйте что-то вроде приведенного ниже примера, в противном случае Непроверенное исключение будет достаточно.

public Response getSomething(Request req) throws Exception{
    if (req.someProperty == 1) {
        Response res = new Response();
        // logic 
    } else {
        thows Exception("Some messages go here")
    }
}

Я призываю вассделайте так:

public Response getSomething(Request req){
if (req.someProperty == 1) {
        Response res = new Response();
        // logic 
        return res;
    } else {
        return ErrorResponse("error message"); // or throw RuntimeException here if you want to
    }
}

Для получения более подробной информации, Kotlin, о которой я упоминал ранее, не поддерживает Проверенное исключение по многим причинам.

Следующеепример интерфейса JDK, реализованного классом StringBuilder:

Appendable append(CharSequence csq) throws IOException;

О чем говорит эта подпись?Он говорит, что каждый раз, когда я добавляю строку к чему-либо (StringBuilder, какой-то журнал, консоль и т. Д.), Я должен ловить эти IOExceptions.Зачем?Потому что он может выполнять IO (Writer также реализует Appendable) ... Таким образом, он приводит к такому виду кода повсюду:

try {
    log.append(message)
}
catch (IOException e) {
    // Must be safe
}

И это не хорошо, см. ЭффективноJava, 3-е издание, элемент 77 : не игнорируйте исключения.

Просмотрите следующие ссылки:

0 голосов
/ 27 декабря 2018

это кажется неправильным, когда намеренно выдает исключение, а затем непосредственно его перехватывает, его можно изменить следующим образом:
может изменить throw new Exception("xxxx"); на res.setMessage("xxxx");,
, а затем сохранить часть перехвата исключениячтобы поймать исключение, которое может произойти внутри бизнес-логики.

public Response getABC(Request requst) {
  Response res = new Response();
  try{
      if(request.someProperty == 1){
          //business logic
      else{
         res.setMessage("xxxx");
      }
  }catch(Exception e){
      res.setMessage(e.getMessage);
  }
  return res;
}
0 голосов
/ 27 декабря 2018

Прежде всего, действуйте более осторожно при рефакторинге метода работы, особенно если вы выполняете рефакторинг вручную.Тем не менее, введение переменной для хранения message может быть одним из способов изменить конструкцию:

public Response getABC(Request requst) throw Excetpions {
    String message = "";
    try{
        if(request.someProperty == 1){
            //business logic
        else{
           message = "xxxx";
        }
    }catch(Exception e){
        message = e.getMessage();
    }
    Response res = new Response();
    res.setMessage(message);
    return res;
}

Предполагается, что business logic делает свое собственное возвращение в случае успеха.

0 голосов
/ 27 декабря 2018

если вы вызываете исключение из метода, тогда зачем его ловить?либо вы возвращаете ответ с сообщением "xxxx", либо выкидываете исключение для вызывающего этого метода, чтобы обработать его.

public Response getABC(Request requst) {
    Response res = new Response();
        if(request.someProperty == 1){
            //business logic
        else{
           res.setMessage("xxxx");
        }
    }
    return res;
}

ИЛИ

public Response getABC(Request requst) throw Excetpions {
    Response res = new Response();
        if(request.someProperty == 1){
            //business logic
        else{
           throw new Exception("xxxx");
        }
    return res;
}


public void someMethod(Request request) {
    try {
        Response r = getABC(request);
    } catch (Exception e) {
        //LOG exception or return response with error message
        Response response = new Response();
        response.setMessage("xxxx");
        retunr response;
    }

}
0 голосов
/ 27 декабря 2018

Нет смысла бросать исключение в блок try и сразу же его перехватывать, если только блок catch не выбрасывает другое исключение.

Ваш код будет иметь больше смысла таким образом:

public Response getABC(Request request) {
    Response res = new Response();
    if (request.someProperty == 1) {
        // business logic
    } else {
        res.setMessage("xxxx");
    }
    return res;
}

Блок try-catch вам нужен только в том случае, если ваша бизнес-логика (выполняемая при условии true) может выдавать исключения.

Если вы не поймаете исключение (что означает, что вызывающий будет иметьчтобы справиться с этим), вы можете обойтись без предложения else:

public Response getABC(Request request) throws Exception {
    if (request.someProperty != 1) {
        throw new Exception("xxxx");
    }

    Response res = new Response();
    // business logic
    return res;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...