2012-04-19 4 views
7
public class PageNotFoundException : HttpException 
{ 
    public PageNotFoundException() 
     : base(404, "HTTP/1.1 404 Not Found") 
    { 

    } 
} 

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

throw new HttpException(404, "HTTP/1.1 404 Not Found") 

Я предпочел бы написать

throw new PageNotFoundException(); 

Я собирался добавить перегрузку для включения InnerException однако я никогда не буду использовать это в блоке try/catch.

Вы считаете эту хорошую практику?
Т.е. наследование от исключения и передача жестко запрограммированной информации на базу (...).

ответ

4

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

(1) Ответ. Это не очень хорошая практика. Вместо этого вы должны использовать метод компоновщика исключений, который напрямую вызывает HttpException.

public static void ThrowPageNotFoundException() { 
    throw new HttpException((Int32)HttpStatusCode.NotFound, "HTTP/1.1 404 Not Found"); 
} 

(2) DO. Используйте методы построения исключений (например, код, который я предоставил). Это позволяет избежать дополнительных затрат на производительность, связанных с вашим собственным типом исключения, и позволяет ему быть встроенным. Члены, бросающие исключения, не получают вложения. Это было бы правильной заменой удобного метания.

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

(4) НЕ. Выбросьте базовый класс System.Exception. Вместо этого используйте конкретный тип исключения.

(5) НЕ. Создавайте пользовательские исключения для удобства. Это не является хорошей причиной для специального исключения, поскольку исключения изначально являются дорогостоящими.

(6) НЕ. Создавайте собственные исключения, чтобы иметь свой собственный тип исключения.

(7) НЕ. Выбросьте исключения, которых можно избежать, изменив код вызова. Это предполагает, что у вас есть ошибка использования в API, а не фактическая проблема.

Любой, кто ознакомился с Руководством по дизайну рамок из серии разработки .NET, будет знать эту практику, и это очень хорошие практики. Это те самые методы, на которых была построена платформа .NET, и MVC.

+0

Это веб-сайт MVC. При запросе объекта с идентификатором, который не существует, я делаю ошибку 404. Что не так с этим? Этот метод использует сам StackOverflow. Попробуйте перейти на http://stackoverflow.com/questions/1022181121312312331 – Marko

+1

Исключения - это не что иное, как быстрое. Выброс исключения происходит в исключительных состояниях - метод inline в этом случае не имеет смысла. – zmbq

+0

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

2

Если вы выбрали исключение в первую очередь, то да - это нормально. Однако, если вы поймаете HttpException, а затем попробуйте бросить PageNotFoundException, вместо этого вы должны поместить исходное исключение как InnerException.

+0

AS, упомянутый выше ... «Я собирался добавить перегрузку для включения innerException, но никогда не буду использовать это в блоке try/catch». – Marko

+0

О, это вы имели в виду? Хорошо, тогда. Так что это хорошая практика. – zmbq

1

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

В ваших собственных библиотеках, если вы согласны с тем, что вы бросаете исключение PageNotFoundException всякий раз, когда должно быть выбрано HttpException 404, может возникнуть смысл в catch (PageNotFoundException). Однако, когда вы начинаете использовать другие библиотеки, у которых нет своего настраиваемого исключения, вы пропустите 404 HttpExceptions, созданных другим кодом. Аналогичным образом, если у вас есть другие разработчики, которые вносят свой вклад в более поздний срок (или даже ваши собственные дополнения в будущем), соображение, что PageNotFoundExceptions - это то, что улавливается большинством функций, может быть пропущено, и новые 404 HttpExceptions могут быть добавлены в новые модули , который также не будет улавливаться копированием/вставленным кодом вызова.

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

С другой стороны, существует определенная ценность для централизации генерации ваших HttpExceptions, если вы ищете, по сути, преимущества фабричных шаблонов; возможно, стоит просто пойти с этим, если это то, что вы пытаетесь выбраться из него (throw ExceptionFactory.NewPageNotFound()).

+0

Подумайте об этом. Это веб-сайт MVC, который занимается множеством разных объектов. Скажем, пользователь в нашем случае. Когда пользователь не существует, я бросаю исключение 404 Not Found. Это то, что делает этот код выше. Хотя я согласен с вами в новых соглашениях, действительно ясно, где это новое исключение, потому что оно широко присутствует в большинстве контроллеров. Я рассматривал возможность использования подхода @David Andersons, но я предпочитаю бросать фактическое исключение в мои контроллеры, а не через статический метод, потому что я выбрал другие исключения аналогичным образом и, скорее, не имел бы статического метода для каждого. – Marko

+0

Как и все соглашения, это проблема только в том случае, если есть проблема, связанная и поддерживающая соглашение. Если это не проблема для вас, то это, безусловно, элегантный способ поддерживать методы фабрики исключений, как вы говорите, код соответствует остальной части вашего кода исключения. – Tanzelax

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