Правильные методы обработки ошибок для уровня данных - PullRequest
0 голосов
/ 28 мая 2009

Что стоит проверить в отношении обработки ошибок, когда вы имеете дело с уровнем доступа к данным? Например, давайте предположим, что у меня есть эта функция ..

    Public Function UserExists(ByVal userName As String) As DataTable
        Dim dt As Object = Nothing
        Dim arSqlParameters(0) As SqlParameter
        arSqlParameters(0) = New SqlParameter("@UserName", SqlDbType.NVarChar, 50)
        arSqlParameters(0).value = userName
        dt = ABC.APP.DAL.DALHelper.ExecuteDatatable(ConnectionString, CommandType.StoredProcedure, "dbo.aspnet_sprGetUserByUsername", arSqlParameters)
        Return dt
    End Function

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

Я новичок в vb.net, и в приложении, над которым я работаю, нет обработки ошибок, поэтому я подумал, что это будет лучшее место для поиска советов. Заранее спасибо:)

Ответы [ 5 ]

1 голос
/ 28 мая 2009

Не уверен, почему вы не объявляете dt как datatable - какова мотивация для "dim dt as object = nothing"?

На самом деле единственная строка, которая может разумно завершиться неудачей, - это вызов "dt = ABC.APP.DAL ....".

В этой строке может быть несколько ошибок:

  • Хранимая процедура или параметр имена неверны. Это должно быть пойман во время разработки (не встроенный механизм проверки, но первый раз, когда вы пытаетесь запустить код)
  • Произошла ошибка в сохраненном процедура. Sprocs использует отложенное имя разрешение, которое может привести к времени выполнения ошибки, если (например) объекты не существует в то время, когда sproc называется. Опять же это самое скорее всего, он поднимает голову при тестировании.
  • тупик. В этом случае вам следует поймать и повторно отправить партию. Здесь вступление и набор ссылок по обработке ошибок SQL в приложении код.
  • Передаваемый параметр неверный (слишком длинный, неправильный тип данных, так далее). Это должно быть проверено до вы называете спрок.
1 голос
/ 28 мая 2009

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

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

Не вижу смысла в том, чтобы в каждом методе обнаруживалась проблема с базой данных. Вы просто повторяете код для сценария, который может взорвать любую часть вашего уровня данных. При этом, если вы решите отлавливать ошибки в БД (или другие общие ошибки) в этом методе, по крайней мере, установите для innerexception значение перехваченного исключения, если вы генерируете новое исключение. Или лучше, войдите, что вы хотите, а затем просто «бросить», а не «бросить экс». Он сохранит исходную трассировку стека.

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

1 голос
/ 28 мая 2009

поиск кода с открытым исходным кодом ORM-решений ( Subsonic , nHibernate ) поможет вам.

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

1 голос
/ 28 мая 2009
0 голосов
/ 28 мая 2009

Я тоже много думал об этом. Многое зависит от конкретной базы данных, поэтому в зависимости от того, используете ли вы SQL2000 или SQL2005 +, вы будете использовать либо коды возврата, либо RAISERROR, либо TRY-CATCH в хранимой процедуре.

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

Код возврата не подлежит взаимодействию без чтения исходного кода хранимой процедуры. возвращаемое значение 0 может быть успешным, неудачным, затронутым 0 строками, только что сгенерированным первичным ключом, или что код возврата не был установлен в зависимости от прихотей создателя хранимой процедуры в тот день. Кроме того, ADO.NET возвращает количество строк из ExecuteNonQuery, поэтому некоторым разработчикам будет сложно быстро найти код возврата.

Специальные решения тоже плохие, например.

IF @@Error>0 
   SELECT 'Something bad happened'

Если у вас есть возможность использовать хранимые процедуры CLR, то в игру вступает обработка ошибок в стиле C #.

Поэтому добавьте RAISERROR в свои хранимые процедуры, затем перехватите SqlException, сообщите пользователю все, что действительно является проверкой ввода пользовательских данных, зарегистрируйте все, что разработчик злоупотребляет API, и, возможно, попытайтесь повторить попытку подключения или выполнения. таймауты.

IF @Foo =42
        BEGIN
            RAISERROR ( 'Paramater @foo can''t be 42',
                16, -- Severity = Misc. User Error.
                1 -- State. == ad hoc way of finding line of code that raised error
               ) ;  
            RETURN -1; --Just because some developers are looking for this by habit
        END 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...