Використання функції try / catch для запобігання збоям програми


79

Я працюю над додатком для Android, який try/catchчасто використовує для запобігання його збою навіть у місцях, де немає потреби. Наприклад,

Погляд у xml layoutз id = toolbarпосилається на:

// see new example below, this one is just confusing
// it seems like I am asking about empty try/catch
try {
    View view = findViewById(R.id.toolbar);
}
catch(Exception e) {
}

Цей підхід використовується у всій програмі. Трасування стека не друкується, і насправді важко знайти, що пішло не так. Додаток раптово закривається, не надрукувавши жодного сліду стека.

Я попросив свого старшого пояснити мені це, і він сказав:

Це для запобігання збоїв у виробництві.

Я абсолютно з цим не згоден . Для мене це не спосіб запобігти збоям програм. Це показує, що розробник не знає, що він / вона робить, і сумнівається.

Чи такий підхід використовується у промисловості для запобігання збоїв корпоративних програм?

Якщо try/catchце насправді, насправді наша потреба, то чи можна приєднати обробник винятків за допомогою потоку інтерфейсу користувача або інших потоків і вловити все там? Це буде кращий підхід, якщо це можливо.

Так, порожньо try/catchпогано , і навіть якщо ми виводимо трасування стеки або виключення журналу на сервер, упаковка блоки коду в try/catchвипадковому порядку по всьому додатком не мають сенсу для мене , наприклад , коли кожна функція полягає в try/catch.

ОНОВЛЕННЯ

Оскільки це питання привернуло багато уваги, і деякі люди неправильно його інтерпретували (можливо, тому, що я його не сформулював чітко), я збираюся переформулювати його.

Ось що тут роблять розробники

  • Функція записується і тестується , це може бути невелика функція, яка просто ініціалізує подання, або складна, після тестування вона обертається навколо try/catchблоку. Навіть для функції, яка ніколи не призведе до винятків.

  • Ця практика використовується у всій програмі. Іноді трафік стека друкується, а інколи просто a debug logіз деяким випадковим повідомленням про помилку. Це повідомлення про помилку відрізняється від розробника до розробника.

  • При такому підході програма не виходить з ладу, але поведінка програми стає невизначеною. Навіть іноді важко простежити, що пішло не так.

  • Справжнім запитанням, яке я задавав, було; Чи дотримується у галузі практика запобігання збоїв корпоративних програм? і я не питаю про порожні спроби / лови . Це як, користувачі люблять програми, які не виходять з ладу, ніж програми, які ведуть себе несподівано? Тому що це справді зводиться або до його збою, або перед користувачем порожнім екраном, або поведінки, про яку користувач не знає.

  • Я публікую тут кілька фрагментів з реального коду

      private void makeRequestForForgetPassword() {
        try {
            HashMap<String, Object> params = new HashMap<>();
    
            String email= CurrentUserData.msisdn;
            params.put("email", "blabla");
            params.put("new_password", password);
    
            NetworkProcess networkProcessForgetStep = new NetworkProcess(
                serviceCallListenerForgotPasswordStep, ForgotPassword.this);
            networkProcessForgetStep.serviceProcessing(params, 
                Constants.API_FORGOT_PASSWORD);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
     private void languagePopUpDialog(View view) {
        try {
            PopupWindow popupwindow_obj = popupDisplay();
            popupwindow_obj.showAsDropDown(view, -50, 0);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    void reloadActivity() {
        try {
            onCreateProcess();
        } catch (Exception e) {
        }
    }
    

Це не дублікат найкращих практик обробки винятків Android , тому OP намагається вловити виняток з іншою метою, ніж це питання.


11
Не відповідаючи на ваше запитання, але ніколи не ковтайте винятки catch(Exception e){}- цей коментар мав сенс до редагування питання
Страшний вомбат


29
Ах, сумнозвіснийON ERROR RESUME NEXT
Дедулікатор

Коментарі не призначені для розширеного обговорення; цю розмову переміщено до чату .
Бхаргав Рао

1
Це запитання змусило мене задуматися, оскільки я також
часто

Відповіді:


81

Звичайно, завжди є винятки з правил, але якщо вам потрібно емпіричне правило - тоді ви праві; порожні блоки лову - "абсолютно" погана практика.

Давайте детальніше розглянемо, спочатку починаючи з вашого конкретного прикладу:

try {
  View view = findViewById(R.id.toolbar);
}
catch(Exception e) { }

Отже, створюється посилання на щось; а коли це не вдається ... неважливо; тому що це посилання спочатку не використовується! Вищезазначений код - абсолютно марний лінійний шум . Або той, хто написав цей код, спочатку припускає, що другий, подібний виклик магічним чином більше не призведе до винятку ?!

Можливо, це мало виглядати так:

try {
  View view = findViewById(R.id.toolbar);
  ... and now do something with that view variable ...
}
catch(Exception e) { }

Але знову ж таки, що це допомагає ?! Існують винятки для передачі, відповідно, поширення ситуацій помилок у коді. Ігнорування помилок рідко буває гарною ідеєю. Насправді, виняток можна розглядати такими способами:

  • Ви надаєте відгук користувачеві; (наприклад: "введене вами значення не є рядком, спробуйте ще раз"); або брати участь у більш складній обробці помилок
  • Можливо, проблему якимось чином очікують і її можна пом'якшити (наприклад, давши відповідь "за замовчуванням", коли якийсь "віддалений пошук" не вдався)
  • ...

Коротше кажучи: мінімальна річ, яку ви робите за винятком, це реєстрація / відстеження; так що, коли ви пізніше будете налагоджувати якусь проблему, ви зрозумієте "Добре, на цей момент стався виняток".

І як зазначали інші: ви також уникаєте ловити Exception загалом (ну, залежно від рівня: можуть бути вагомі причини, щоб мати якийсь catch для Exception , і навіть деякі види Помилок на найвищому рівні, щоб переконатися, що нічого не губиться; ніколи ).

Нарешті, давайте процитуємо Уорда Каннінгема:

Ви знаєте, що працюєте з чистим кодом, коли кожна прочитана процедура виявляється майже такою, як ви очікували. Ви можете назвати його прекрасним кодом, коли з коду також виглядає так, ніби мова створена для проблеми.

Нехай це занурюється і розмірковує про це. Чистий код вас не дивує. Приклад, який ви показуєте нам, дивує всіх, на кого дивиться.

Оновлення щодо оновлення , про яке запитує операційна програма

try {
  do something
}
catch(Exception e) { 
  print stacktrace
}

Та сама відповідь: робити те, що "всюди", також є поганою практикою. Тому що цей код також дивує читача.

Вище:

  • Десь друкує інформацію про помилку. Зовсім не гарантується, що це "десь" нагадує розумне призначення. Навпаки. Приклад: у програмі, з якою я працюю, такі дзвінки чарівним чином відображатимуться в наших буферах трасування. Залежно від контексту, наш додаток може іноді перекачувати в ці буфери тонни і тони даних; роблячи ці буферні обрізки кожні кілька секунд. Тож "просто помилки друку" часто перекладається як "просто втратити всю таку інформацію про помилки".
  • Тоді: ви не намагаєтесь / ловите, бо можете . Ви робите це, тому що розумієте, що робить ваш код; і ти знаєш: мені краще спробувати / зловити тут, щоб зробити правильну справу (див. перші частини моєї відповіді ще раз).

Отже, використовуючи try / catch як "шаблон", як ви показуєте; це як сказано: все ще не гарна ідея. І так, це запобігає збої; але призводить до всякого роду "невизначеної" поведінки. Ви знаєте, коли ви просто вловлюєте виняток, замість того, щоб правильно з ним боротися; ви відкриваєте банку з глистами; тому що ви можете зіткнутися з безліччю подальших помилок, які згодом не зрозумієте. Оскільки ви споживали подію "першопричини" раніше; надрукував десь; і що десь зараз немає.


1
Що робити, якщо я надрукую трасування стека? Я все ще не думаю, що мені тут потрібно спробувати / зловити.
mallaudin

3
Треба визнати, що я не отримую вашої редакції. Не справжня ідея, що ви там робите; або куди ви з цим дійшли.
GhostCat

@mallaudin в загальному випадку все, що буде після рядка, який виходить з ладу, програма не буде виконуватися (obvs), тому друк - це просто дурниця. У цьому конкретному випадку, тобто спробуйте + за винятком, принаймні щось буде показано, а виняток не буде замовчуватися.
Пітер Бадіда

2
@GhostCat ОП повідомляє про коментар в іншій відповіді, що блоки винятків вже містять дзвінки реєстрації. Питання спотворює, що насправді відбувається, тому я не думаю, що звинувачення старшого розробника у некомпетентності тут корисно. Я думаю, що відбувається не тільки те, що нам дає ОП.
jpmc26,

1
@GhostCat справа не в репо, я просто зрозумів, що мій приклад був поганим. Всі думали, що я запитую про порожню спробу / зловити
mallaudin

15

З документації Android :

Давайте назвемо це як -

Не ловіть загальне виняток

Також може бути спокуса лінуватися, ловлячи винятки, і робити щось подібне:

try {
    someComplicatedIOFunction();        // may throw IOException
    someComplicatedParsingFunction();   // may throw ParsingException
    someComplicatedSecurityFunction();  // may throw SecurityException
    // phew, made it all the way
} catch (Exception e) {                 // I'll just catch all exceptions
    handleError();                      // with one generic handler!
}

Майже у всіх випадках недоречно ловити загальний Exceptionабо Throwable (бажано не Throwable, оскільки він включає винятки про помилки). Це дуже небезпечно, оскільки означає, що винятки, яких ви ніколи не очікували (включаючи RuntimeExceptionsподібні ClassCastException), потрапляють в обробку помилок на рівні програми.

Це затуляє властивості обробки несправностей вашого коду, тобто якщо хтось додає новий тип Exceptionдо коду, який ви викликаєте, компілятор не допоможе вам зрозуміти, що вам потрібно обробляти помилку інакше .

Альтернативи лову загального винятку:

  • Ловіть кожен виняток окремо як окремі блоки лову після однієї спроби. Це може бути незручно, але все ж переважніше, ніж ловити всі винятки.
    Редагувати за автором: Це мій вибір. Обережно повторюйте занадто багато коду в блоках catch. Якщо ви використовуєте Java 7 або новішу версію, використовуйте мульти-catch, щоб уникнути повторення того самого блоку catch.
  • Переформатуйте свій код, щоб мати більш точну обробку помилок , із кількома блоками спроб. Розділіть введення-вивід із розбору, обробляйте помилки окремо в кожному випадку.
  • Повторно викиньте виняток . Багато разів все одно не потрібно ловити виняток на цьому рівні, просто нехай метод кидає його.

У більшості випадків ви не повинні обробляти різні типи винятків однаково.

Форматування / розміщення абзаців дещо змінено з джерела для цієї відповіді.

PS Не бійтеся винятків !! Вони є друзями!!!


1
якщо ви ловите кожен виняток окремо, переконайтеся, що не продовжуєте виконувати у невизначеному стані (уникайте подібних речей Object a; try { a = thing(); } catch (Exception e) {...} try { a.action(); } catch (Exception e) {...}))
njzk2

Справедливості заради, ловити загальний Exceptionзасіб може бути корисним як частина системи "журналу перед збоєм", хоча в такому випадку його слід відновити.
Джастін Тайм - поновити Моніку

9

Я б поставив це як коментар до іншої відповіді, але у мене поки що немає репутації.

Ви правильно говорите, що це погана практика, насправді те, що ви опублікували, показує різні типи поганої практики щодо винятків.

  1. Відсутність обробки помилок
  2. Загальний улов
  3. Жодних навмисних винятків
  4. Ковдра Спробуй / злови

Я спробую пояснити все це на цьому прикладі.

try {
   User user = loadUserFromWeb();     
   if(user.getCountry().equals("us")) {  
       enableExtraFields();
   }
   fillFields(user);   
} catch (Exception e) { 
}

Це може призвести до збою кількома способами, які слід вирішувати по-різному.

  1. Поля не заповнюються, тому перед користувачем відображається порожній екран, а потім ... що? Нічого - відсутність обробки помилок.
  2. Не існує різниці між різними типами помилок, наприклад, проблемами в Інтернеті або проблемами з самим сервером (збій, невдалий запит, пошкоджена передача, ...) - загальний улов.
  3. Ви не можете використовувати винятки у власних цілях, оскільки поточна система цьому заважає. - Ніяких навмисних винятків
  4. Неосновні та несподівані помилки (наприклад, null.equals (...)) можуть спричинити неможливість виконання основного коду. - Ковдра спробувати / зловити

Рішення

(1) Перш за все, мовчки невдача - це не дуже добре. Якщо сталася помилка, програма не працюватиме. Натомість має бути спроба вирішити проблему або відобразити попередження, наприклад "Не вдалося завантажити дані користувача, можливо, ви не підключені до Інтернету?". Якщо програма робить не те, що повинна, це ще більше засмучує користувача, ніж якщо воно просто закривається.

(4) Якщо Користувач неповний, наприклад, країна невідома і повертає нуль. Метод equals створить NullPointerException. Якщо цей NPE просто кинутий і схоплений, як зазначено вище, метод fillFields (користувач) не буде викликаний, хоча він все одно може бути виконаний без проблем. Ви можете запобігти цьому, включивши нульові перевірки, змінивши порядок виконання або відрегулювавши область спроби / лову. (Або ви можете зберегти кодування таким чином: "us" .equals (user.getCountry ()), але мені довелося навести приклад). Звичайно, будь-який інший виняток також запобіжить виконанню fillFields (), але якщо немає користувача, ви, мабуть, не хочете його виконувати в будь-якому випадку.

(1, 2, 3) Завантаження з Інтернету часто викликає різноманітні винятки, від IOException до HttpMessageNotReadable винятку, навіть до просто повернення. Можливо, користувач не підключений до Інтернету, може бути, що відбулася зміна серверного сервера або він не працює, але ви не знаєте, тому що ви ловите (виняток) - натомість вам слід ловити конкретні винятки. Ви навіть можете зловити декілька з них таким

try{
   User user = loadUserFromWeb(); //throws NoInternetException, ServerNotAvailableException or returns null if user does not exist
   if(user == null) { 
       throw new UserDoesNotExistException(); //there might be better options to solve this, but it highlights how exceptions can be used.
   }
   fillFields(user);
   if("us".equals(user.getCountry()) {
       enableExtraFields();
   }
} catch(NoInternetException e){
    displayWarning("Your internet conneciton is down :(");
} catch(ServerNotAvailableException e){
    displayWarning("Seems like our server is having trouble, try again later.");
} catch(UserDoesNotExistException e){
    startCreateUserActivity();
}

Сподіваюся, це пояснює це.

Щонайменше, як швидке виправлення, ви можете надіслати подію у свій сервер, за винятком. Наприклад, через firebase або crashlytics. Таким чином, ви можете принаймні бачити подібні речі (привіт, основна діяльність не завантажується для 80% наших користувачів через таку проблему, як (4).


8

Це, безумовно, погана практика програмування.

З поточного сценарію, якщо try catchподібних є сотні , ви навіть не знаєте, де відбувається виняток, не налагоджуючи програму, що є кошмаром, якщо ваша програма знаходиться у виробничому середовищі.

Але ви можете включити реєстратор, щоб дізнатися, коли виникає виняток (і чому). Це не змінить ваш звичайний робочий процес.

...
try {
    View view = findViewById(R.id.toolbar);
}catch(Exception e){
    logger.log(Level.SEVERE, "an exception was thrown", e);
}
...

7

Це погана практика. Інші відповіді говорять про це, але я думаю, що важливо відступити назад і зрозуміти, чому ми маємо винятки.

Кожна функція має пост-умову - набір речей, які повинні бути істинними після виконання цієї функції. Наприклад, функція, яка читає з файлу, має умову post, що дані у файлі будуть прочитані з диска та повернуті. Тож виняток виникає, коли функція не змогла задовольнити жодної зі своїх пост-умов.

Ігноруючи виняток із функції (або навіть фактично ігноруючи його, просто реєструючи виняток), ви говорите, що з цією функцією ви в порядку, не виконуючи фактично всю роботу, за якою вона погодилась. Це здається малоймовірним - якщо функція працює неправильно, немає жодних гарантій того, що те, що далі, буде виконуватися взагалі. І якщо решта вашого коду працює нормально, незалежно від того, працює певна функція чи ні, то хтось дивується, навіщо у вас ця функція в першу чергу.

[Зараз є певні випадки, коли порожні catches - це нормально. Наприклад, ведення журналу - це те, чим ви можете виправдати загортання в порожній улов. Ваша програма, ймовірно, буде працювати нормально, навіть якщо деякі журнали неможливо записати. Але це особливі випадки, над якими вам доведеться попрацювати, щоб знайти в звичайному додатку.]

Отже, справа в тому, що це погана практика, оскільки вона насправді не підтримує роботу вашого додатка (передбачуване виправдання цього стилю). Можливо, технічно ОС не вбила його. Але навряд чи програма все ще працює належним чином після простого ігнорування винятку. А в найгіршому випадку це насправді може завдати шкоди (наприклад, пошкодити файли користувачів тощо).


3

Це погано з багатьох причин:

  1. Що ви робите, що findViewByIdстворює виняток? Виправте це (і скажіть мені, бо я цього ніколи не бачив) замість ловити.
  2. Не вловлюйте, Exceptionколи ви можете зловити певний тип винятку.
  3. Існує таке переконання, що хороші програми не дають збою. Це не правда. Хороший додаток аварійно завершує роботу, якщо повинен.

Якщо програма переходить у поганий стан, їй набагато краще вийти з ладу, ніж програвати її у непридатному стані. Побачивши NPE, не слід просто вкладати нульовий чек і йти геть. Кращий підхід - з’ясувати, чому щось є нульовим, або зупинити його від нульового значення, або (якщо нульове значення виявляється дійсним і очікуваним станом) перевірити на нульове значення. Але ви повинні розуміти, чому проблема виникає в першу чергу.


2

Я розробляв програми для Android протягом останніх 4-5 років і ніколи не використовував спробу catch для ініціалізації перегляду.

Якщо це панель інструментів, зробіть так

Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);

наприклад: - Щоб отримати TextView із подання (фрагмент / діалог / будь-який власний вигляд)

TextView textview = (TextView) view.findViewById(R.id.viewId);

TextView textview = (TextView) view.findViewById (R.id.viewId);

замість цього

View view = findViewById(R.id.toolbar);

Об’єкт перегляду має мінімальне охоплення порівняно з його реальним видом перегляду.

Примітка: - Можливо, воно аварійно завершилось, оскільки подання було завантажено. Але додавання try catch - погана практика.


У багатьох випадках відкидання перегляду не є необхідним. У вас є кілька методів, Viewякі можуть бути вже корисними (наприклад setVisibility()), без вказівки, який саме клас використовується. (наприклад, у випадку з макетом, який можна періодично змінювати)
njzk2

1

Так, функція try / catch використовується для запобігання аварійному завершенню роботи програми, але вам, звичайно, не потрібна функція try / catch для отримання подання з XML, як показано у вашому запитанні.

try / catch зазвичай використовується під час створення будь-якого http-запиту, під час синтаксичного аналізу будь-якого рядка до URL-адреси, створення URL-зв’язків тощо, а також обов’язково надрукуйте трасування стека. Не друкувати це не має особливого сенсу оточувати його за допомогою try / catch.


1

Як вже було сказано раніше, загальні винятки не слід вловлювати або, принаймні, лише в декількох центральних місцях (зазвичай вони розміщені у фреймворку / коді інфраструктури, а не в коді програми). Якщо ловити загальні винятки та реєструвати їх, додаток слід згодом вимкнути або, принаймні, користувачеві слід повідомити, що програма потенційно перебуває в нестабільному стані та може статися пошкодження даних (якщо користувач вирішить продовжити виконання). Тому що це може трапитися, якщо ви вловите всілякі винятки (не вистачає пам’яті, щоб назвати одне) і залиште програму у невизначеному стані.

IMHO гірше ковтати винятки та ризикувати цілісністю даних, втратою даних або просто залишати програму у невизначеному стані, ніж дозволяти програмі аварійно завершувати роботу, і користувач знає, що щось пішло не так, і може спробувати знову. Це також призведе до кращих повідомлень про проблеми (більше в основі проблеми), ймовірно, менше різних симптомів, ніж якщо ваші користувачі почнуть повідомляти про всі проблеми, що виникають із невизначеного стану програми.

Після того, як централізована обробка винятків / ведення журналу / звітування та контрольоване вимкнення буде застосована, починайте переписувати обробку винятків, щоб вловити локальні винятки як можна конкретніше. Постарайтеся зробити блок try {} якомога коротшим.


1

Дозвольте додати свою точку зору, як хлопець, який працює у галузі корпоративного мобільного розвитку вже більше десяти років. По-перше, кілька загальних порад щодо винятків, більшість з яких містяться у відповідях вище:

  • Винятки слід використовувати для виняткових, несподіваних або неконтрольованих ситуацій, а не регулярно у всьому коді.
  • Програміст повинен знати частини коду, сприйнятливі для викидів винятків, і намагатися їх зловити, залишаючи решту коду максимально чистим.
  • Як правило, винятки не слід залишати без уваги.

Зараз, коли ви розробляєте не додаток для себе, а для компанії чи корпорації, зазвичай стикаються з додатковими вимогами щодо цієї теми:

  • "Збої програм показують поганий імідж компанії, тому вони неприйнятні". Тоді слід виконати ретельну розробку, і можливим виявленням навіть неймовірних винятків. Якщо так, це потрібно робити вибірково і дотримуватися розумних меж. І зауважте, що розробка не стосується лише рядків коду, наприклад, інтенсивний процес тестування є критичним у цих випадках. Однак несподівана поведінка в корпоративному додатку гірша, ніж збій. Отже, кожного разу, коли ви ловите виняток у своєму додатку, ви повинні знати, що робити, що показувати та як поводитиметься програма далі. Якщо ви не можете керувати цим, нехай програма не працює.
  • "Журнали та сліди стека можуть скидати конфіденційну інформацію на консоль. Це може бути використано для зловмисника, тому з міркувань безпеки їх не можна використовувати у виробничому середовищі". Ця вимога суперечить загальному правилу для розробника не писати тихі винятки, тому вам доведеться знайти спосіб для цього. Наприклад, ваш додаток може контролювати навколишнє середовище, тому він використовує журнали та сліди стеків у невиробничих середовищах, одночасно використовуючи хмарні інструменти, такі як bugsense, crashlitics або подібні для виробничих середовищ.

Отже, коротка відповідь полягає в тому, що код, який ви знайшли, не є добрим прикладом практики, оскільки його важко і дорого підтримувати, не покращуючи якість програми.


1

Інша точка зору - як хтось, хто пише щоденне корпоративне програмне забезпечення, якщо у додатку виникає невиправлена ​​помилка, я хочу, щоб вона аварійно завершила роботу . Крах бажаний. Якщо він виходить з ладу, він реєструється. Якщо за короткий проміжок часу він аварійно завершує роботу кілька разів, я отримую електронне повідомлення про те, що програма аварійно завершує роботу, і я можу переконатися, що наш додаток і всі веб-служби, які ми споживаємо, все ще працюють.

Отже питання:

Є

try{
  someMethod();
}catch(Exception e){}

гарна практика? Ні! Ось кілька моментів:

  1. НАЙГОЛОВНІШЕ: це погана взаємодія з клієнтами. Як я повинен знати, коли щось погане відбувається? Мої клієнти намагаються використовувати мій додаток, і нічого не працює. Вони не можуть перевірити свій банківський рахунок, оплатити рахунки, що б не робив мій додаток. Мій додаток абсолютно марний, але привіт, принаймні він не розбився! (Частина мене вважає, що цей "Старший" розробник отримує очки брауні за низькі числа збоїв, тому вони іграють у систему.)

  2. Коли я займаюся розробкою і пишу поганий код, якщо я просто ловлю і ковтаю всі винятки на верхньому шарі, у мене немає реєстрації. У мене на консолі нічого немає, і додаток мовчки виходить з ладу. З того, що я можу сказати, все, здається, працює нормально. Тож я фіксую код ... Виявляється, мій об’єкт DAO весь час був нульовим, і платежі клієнта фактично ніколи не оновлювались у БД. Ой! Але мій додаток не вийшов з ладу, тому це плюс.

  3. Граючи в захисника диявола, скажімо, я мав змогу ловити і ковтати всі винятки. Це дуже легко написати обробник виключень в Android. Якщо у вас насправді просто є вловити кожне виняток, ви можете зробити це в одному місці, а не перець try/catchпо всій своїй кодовій базі.

Деякі розробники, з якими я працював раніше, вважали збій поганим.

Я повинен запевнити їх, що ми хочемо, щоб наш додаток вийшов з ладу. Ні, нестабільний додаток не годиться, але збій означає, що ми зробили щось не так, і нам потрібно це виправити. Чим швидше він виходить з ладу, чим раніше ми його знаходимо, тим легше це виправити. Єдиний інший варіант, про який я можу подумати, - це дозволити користувачеві продовжувати невдалий сеанс, який я прирівнюю до роздратування на моїй базі користувачів.


0

Використовувати це погано, catch(Exception e){}оскільки ви по суті ігноруєте помилку. Ви, мабуть, хочете зробити щось подібне:

try {
    //run code that could crash here
} catch (Exception e) {
    System.out.println(e.getMessage());
}

0

Ми використовуємо майже ту саму логіку. Використовуйте try-catchдля запобігання збоям робочих програм.

Винятки НІКОЛИ не слід ігнорувати. Це погана практика кодування. Хлопцям, які підтримують код, буде дуже важко локалізувати частину коду, яка спричинила виняток, якщо вони не зареєстровані.

Ми використовуємо Crashlyticsдля реєстрації винятків. Код не вийде з ладу (але деякі функції будуть порушені). Але ви отримуєте журнал винятків на інформаційній панелі Fabric/Crashlytics. Ви можете переглянути ці журнали та виправити винятки.

try {
    codeThatCouldRaiseError();
} catch (Exception e) {
    e.printStackTrace();
    Crashlytics.logException(e);
}

Так. Це те, що люди роблять тут, але я з цим не погоджуюсь. Тому я розмістив запитання. Чи можете ви придумати щось більш логічне?
mallaudin

4
@mallaudin Не публікуйте приклад коду, який спотворює код, про який ви запитуєте. Це може кардинально змінити отриману відповідь.
jpmc26,

@ jpmc26 так. Я це бачив у відповідях.
mallaudin

0

Хоча я погоджуюсь з іншими відгуками, є одна обставина, з якою я неодноразово стикався, коли цей мотив гранично терпимий. Припустимо, хтось написав трохи коду для класу наступним чином:

private int foo=0;

    . . .

public int getFoo() throws SomeException { return foo; }

За цієї обставини метод 'getFoo ()' не може провалитися - завжди буде встановлено законне значення приватного поля 'foo', яке потрібно повернути. Проте хтось - можливо, з педантичних міркувань - вирішив, що цей метод повинен бути оголошений як потенційно винятковий. Якщо тоді ви спробуєте викликати цей метод у контексті - наприклад, обробнику подій - який не дозволяє кидати виняток, ви в основному змушені використовувати цю конструкцію (навіть тоді, я згоден, що потрібно принаймні реєструвати виняток просто на випадок) . Щоразу, коли мені доводиться це робити, я завжди принаймні додаю великий жирний коментар "ЦЕ НЕ МОЖЕ НАСТУПИТИ" поруч із реченням "catch".

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.