Зачем нужны throw Exception?

weregod

unserializer
Автор оригинала: AmdY
по такому, как пишу require вместо include и выволнение дальше не возможно: недоступен файл
require отсутствующего файла (E_ERROR) можно ловить? :eek:
 

AmdY

Пью пиво
Команда форума
нет, ты же спрашивал об ошибках которые нельзя обработать толком.
 

Вурдалак

Продвинутый новичок
AmdY
Спрашивал я. В случае с require действительно ничего не поделаешь, только разве что в shutdown-функции на последок что-то сообщить пользователю. А что с отвалившейся базой? Выбрасывать ErrorException и ловить как обычно.
 

AmdY

Пью пиво
Команда форума
только такой экцепшин не в любом проекте можно обработать. разве что выплюнуть статичную хатэмэлину.
 

fixxxer

К.О.
Партнер клуба
мне одному кажется, что кто-то путает обработку исключительных ситуаций с валидацией и отображением пользователю текстов ошибок?
 

sverel

Новичок
Во.во. Я давно уже об этом. Логику к логике, ошибки к ошибкам.

А исключения - я пока вообще не понял куда.
 

craz

Нестандартное звание
Автор оригинала: sverel
Во.во. Я давно уже об этом. Логику к логике, ошибки к ошибкам.

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

sverel

Новичок
Все исключительные ситуации, которые Вы можете себе придумать, можно изобразить при помощи if/else

PHP:
$img = imageCreateFromJpeg($someFile);
if ( ! is_resource($img)) {
   // применяем меры.
}
Вот хотелось бы узнать по какому критерию Вы некоторые исключительные ситуации относите к логике (проверка на корректность загруженного файла, проверка на ЧМОД и т.д.), и по каким критериям относите к Exception (подделанный jpeg).

Лично я при загрузке файла сразу проверяю и расширение и корректность картинки.
PHP:
// первая ф-ция проверяет расширение или mime-type.
// Вторая пытается прочекать заголовки jpg-файла.
if ( ! image::isImage($file) || ! image::isRealImage($file)) {
   echo 'Не корректный файл';
}
И мне в, принципе, совершенно без разницы, что юзер залил price.xls или myVirus.exe.jpg. Сообщение об ошибке будет всегда одним и тем же. А плодить лишний код: try/catch + отдельный класс ExceptionImageIsNotRealImage.class.php - только ради того что бы выводить разные сообщения об ошибках?

-~{}~ 10.06.10 13:20:

Т.е. если я правильно понял, Ваш код проверяющий корректность залитого файла (то что у меня на 3 строки) должен выглядеть примерно так:

PHP:
try {

  if ( ! isImage($file)) {
    echo 'Не корректный файл';
  }

  if ( ! isRealImage) {
    throw new ExceptionImageIsNotRealImage();
  }

} catch (ExceptionImageIsNotRealImage $e) {
   echo 'Битый jpg';
}

// и ещё где-то далеко должен быть создан класс ExceptionImageIsNotRealImage
Если да, то Вы очень заботливый человек, раз так заботитесь о хаккерах взламывающих Ваш сайт :)
 

craz

Нестандартное звание
ну возможно пример не раскрывает всей сущности...

>Все исключительные ситуации, которые Вы можете себе придумать, можно изобразить при помощи if/else

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

Вот отлов ошибки и уведомление администратора о чмоде это можно делать как делаете вы, а после отлов нереального jpg возможно потребуется распарсить файл и определить какой это вирус, ну к примеру вы касперский онлайн...)
1)вы не хотите чтобы вам грузили этот файл
2)вам надо знать как можно больше подробностей о файле

вот тут мне кажеться надо выбрасывать исключения...

возможно ситуация надуманная... и на вашем месте если в принципе три страницы доводов вам не дали ответов на ваш вопрос я бы так и делал, как делал раньше...

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

Фанат

oncle terrible
Команда форума
sverel
хороший пример, кстати.
throw - это возможность остановить все остальные проверки, не городя лестницу if-ов
 

sverel

Новичок
эмм. ну 3 страницы доводов это:
1. сначала обсуждали как повысить стабильность, засчет "исправления ошибок на лету" - так описано в агиле-статье из второго поста. Вроде, разобрались, что это не правильный выход.
2. Потом долго обсуждали вывод сообщений об ошибках. Вроде, тоже поняли, что ошибки - ошибками и должны выводится через trigger_error, а исключения - это не ошибки, так что это тоже отмели.
3. Теперь обсуждаем, что исключения - это часть логики. Причем, я пока вижу, что это велосипед образованный от конструкции if/else, но отличающийся от него, тем, что если запускается каскад ф-ций, то return false - придётся обрабатывать во всём каскаде ф-ций, в то время как Exception будет "ПРОБРОШЕН" сразу через все. Например, для сравнения:

PHP:
try {
   uploadFile();
} catch () {
  ...
}

function uploadFile()
{
   ...
   isImage();
   ...
}
function isImage()
{
   ...
   throw new Exception();
   ...
}

В противном случае придётся во всех методах плодить if/else:
PHP:
$result = uploadFile();
if ( ! $result) {
   echo 'Какая-то ошибка';
}


function uploadFile()
{
   ...
   if ( ! isImage()) {
      return false;
   }
   ...
}
function isImage()
{
   ...
   return false;
   ...
}
Теперь до меня дошло, что именно каскадный запуск ф-ций должен быть критерием для БРОСКА исключения, вместо обработки его в if/else. Но никак не исправление ошибок на лету и никак не сообщения об ошибках программы.

-~{}~ 10.06.10 13:44:

Но теперь не понятно, зачем для каждого типа ошибок плодить отдельный класс ExceptionSomeType?
Ведь было бы проще:
PHP:
throw new Exception($type = 'someType');

....
catch {
   switch ($e->type) {
      case 'someType'.....
   }
}
-~{}~ 10.06.10 13:45:

*****
Ага я тоже допёр, пообщавшись с craz-ом.
 

craz

Нестандартное звание
во! согласен на все 100%

где-то глубоко это тоже скрывалось во мне за тоннами не систематизированных знаний)

-~{}~ 10.06.10 13:48:

Но теперь не понятно, зачем для каждого типа ошибок плодить отдельный класс ExceptionSomeType?
Ведь было бы проще:

throw new Exception($type = 'someType');

....
catch {
switch ($e->type) {
case 'someType'.....
}
}
ну тут уже минусы вылазят может? вы ведь знаете как безбожно тратится место внутри классов на всякие сеттеры геттеры и иже сними конструкторы...
 

sverel

Новичок
Автор оригинала: craz
ну тут уже минусы вылазят может? вы ведь знаете как безбожно тратится место внутри классов на всякие сеттеры геттеры и иже сними конструкторы...
Мы же вроде договорились, что Exception нужен ТОЛЬКО для того что бы ПРОБРОСИТЬ, вместо того что бы плодить if/else. А логику, наверное, надо уже писать в блоке catch {}

-~{}~ 10.06.10 13:59:

иначе логика получится реально разбросанной по нескольким местам.
 

craz

Нестандартное звание
Автор оригинала: sverel
Мы же вроде договорились, что Exception нужен ТОЛЬКО для того что бы ПРОБРОСИТЬ, вместо того что бы плодить if/else. А логику, наверное, надо уже писать в блоке catch {}

-~{}~ 10.06.10 13:59:

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

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


try
d:=56/0;
x:=round(d);
except
on Excp : EInvalidOp do
ShowMessage(‘ошибка под названием – ‘+Excp.Message)
else
ShowMessage(‘Другая ошибка’);
end;
вот тут видите вы умерли и пробросили исключение - теперь вы точно знаете где ошибка (Это делфи)(если этого не сделать я если честно уже не помню что будет, но будет реально не удобно...)
 

iceman

говнокодер
sverel
throw new Exception($type = 'someType');
....
catch {
switch ($e->type) {
case 'someType'.....
}
}
в pl/sql при объявление переменных экзепшен объявляется там же...
PHP:
declare
  my_ex Exception;
begin
  raise my_ex;
exception when my_ex then
  raise_application_error(-20182, 'Exception my_ex');
end;
 

FB3

Новичок
sverel
разные классы эксепшенов нужны, чтобы ловить их в разных местах

Если не найден пользователь в базе, то я могу поймать этот exception раньше и создать пользователя, выведу ему страницу приветствия, а если к базе не удалось присоединиться, то я буду ловить в другом месте другой exception и выводить пользователю большой фиг "Приходите позже!".

А в твоем примере ты все эксепшены в одном месте ловишь и обрабатываешь.

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

varan

Б̈́̈̽ͮͣ̈Л̩̲̮̻̤̹͓ДͦЖ̯̙̭̥̑͆А͇̠̱͓͇̾ͨД͙͈̰̳͈͛ͅ
Если не найден пользователь в базе, то я могу поймать этот exception раньше и создать пользователя, выведу ему страницу приветствия
Не знаю, вот я бы не стал так делать. Мне кажется, exception - это для исключительных ситуаций типа падения базы или неправильного файла. А то, что ты описал, это логика приложения. Создавать пользователя по exception, это странновато как-то имхо
 

korchasa

LIMB infected
Автор оригинала: varan
Не знаю, вот я бы не стал так делать. Мне кажется, exception - это для исключительных ситуаций типа падения базы или неправильного файла. А то, что ты описал, это логика приложения. Создавать пользователя по exception, это странновато как-то имхо
Кому как. Подставляйте ведро - вот вам балалайка. Достался нам проект на переделку. Написали и начали запускать - гора 500к в логе. Оппа! Cтрах и ужас - база была в неконсистентном состоянии. Коммент есть, а его автора нет, и т.д. В итоге собственный наследник ActiveRecord, с перекрытым getById():
PHP:
function getById($id) 
{
  try
  {
    return parent::getById($id);
  }
  catch(RecordNotFoundException $e)
  {
    return new DeletedUser();
  }
}
А так да, какие уж "исправления на лету" ;)
 

Raziel[SD]

untitled00
Исключения нужны для перехода на другой уровень логики в случае возникновения нештатной ситуации. Причем важно понимать, что это не обязательно ошибка. Например:

try {
блок генерации контента
if (.....) {//приспичило отправить на другую страницу
throw new MyRedirectException('http://www....');
}
блок генерации контента
}catch (MyRedirectException $e) {
завершение работы :)
редирект
}
 
Сверху