Достаточно ли хорош переводчик системной ошибки в дружественный пользователю? - PullRequest
1 голос
/ 18 июня 2009

Вот как я перевожу сгенерированные ошибки:

        catch (NpgsqlException ex)
        {
            if (tx != null) tx.Rollback();

            if (ex.Message.Contains("foreign key constraint"))
                throw new Exception("Cannot delete this, this record is already referenced on other record(s)");
            else
                throw new Exception(ex.Message, ex.InnerException);
        }

Ошибка ограничения образца Npgsql:

ОШИБКА: 23503: обновить или удалить на столе «цвет» нарушает внешний ключ ограничение "fk_order_detail__color" на таблица "order_detail"

Ответы [ 4 ]

4 голосов
/ 18 июня 2009

Вы удаляете информацию из вашего исключения и не регистрируете ее.

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

Рефакторинг, чтобы это не могло повториться.

2 голосов
/ 18 июня 2009

Если вы хотите более конкретно обработать некоторую ошибку, то в идеале вы должны создать ColorAlreadyUsedException class и выбросить ее. Подумайте, как caller будет различать два случая: нужно ли будет также проверять Сообщение?

По-прежнему включать исходное исключение в качестве внутреннего исключения.

2 голосов
/ 18 июня 2009

Вы должны написать свою проблему таким образом, чтобы она не вызывала ошибок SQL.

Или, если вы знаете конкретную причину возникновения ошибки, просто покажите ее в интерфейсе как сообщение , а не как ошибку. То есть «Вы должны удалить зависимости между удалением этого объекта», а не «внутренняя ошибка: что угодно».

Ошибка - это нечто неожиданное; ошибки ограничения отсутствуют.

1 голос
/ 18 июня 2009

Мне кажется довольно странным полагаться на текст сообщения, когда в нем уже есть код ошибки. В то время как есть некоторые другие проблемы с шаблоном, как обрисовано в общих чертах в других ответах, я бы скорее поискал «23503», а не «ограничение внешнего ключа». В противном случае, что произойдет, если пользовательская база данных будет установлена ​​в другой культуре или обновленная версия сервера изменит текст сообщения?


На самом деле, просматривая некоторую онлайн-документацию , вы используете класс исключений, который выглядит так, как будто есть даже свойство Code, это будет намного быстрее и надежнее по сравнению со свойством сообщения. *


Заключительная мысль ...

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

if (ex.Message.Contains("foreign key constraint"))
    throw new ConstraintException("Cannot delete this, this record is already referenced on other record(s)");
else
     throw;

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

...