Форум программистов, компьютерный форум, киберфорум
C# Windows Forms
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.75/4: Рейтинг темы: голосов - 4, средняя оценка - 4.75
0 / 0 / 0
Регистрация: 01.04.2024
Сообщений: 10

Остановка выполнения кода в после срабатывания ошибки во внешнем классе

16.04.2024, 16:04. Показов 1245. Ответов 12

Студворк — интернет-сервис помощи студентам
Есть приложение, в котором производится работа с БД при помощи библиотеки Npgsql. Для выполнения запросов, не получающих никакие данные, а лишь выполняющие запросы INSERT, DELETE и т.д. был создан метод Query(string query) в отдельном статическом публичном классе Data для использования его во всевозможных формах. Для отлова неправильного запроса/данных в запросе я как обычно пользовался дебагом самого вижака, но решил попробовать обрабатывать ошибку на моменте ExecuteNonQuery() для получения итогового запроса, который будет отправляться в бд. Так как все запросы будут идти через Query(string query) и после этого string query будет попадать в класс Data и в нём будет выполняться cmd.ExecuteNonQuery(), а cmd - это в свою очередь тот самый string query, то я обрабатываю cmd.ExecuteNonQuery() в try catch и с помощью MessageBox хочу выводить итоговый запрос, который отправляется в бд, и если он выполнился с ошибкой, посмотреть, какие данные в итоге получились в самом запросе (например в запросе увидел айдишник 7, которого нет в таблице, на которую ссылаюсь и т.д.).

Проблема в том, что после вывода ошибочного запроса в mbox, выполнение кода в классе, где выполнялся метод Data.Query(), продолжается, хотя я хочу сделать так, что после получения провального запроса я вижу, какой запрос отправился в бд, после чего выполнение кода останавливается.

Блок кода 1 - метод, в котором специально выполняется запрос с ошибкой, т.к. id=5 не существует во внешней таблице.
Блок кода 2 - обработка выполнения запроса с ошибкой, mbox выводит мне запрос, который отправлялся в бд, после чего я бы смог исправлять ошибку в каждом вызывающем методе с ошибкой.

Блок кода 1 (класс AddAssignment)
C#
1
2
3
4
5
6
Data.Query($"INSERT INTO orders(code, name, guarantor_id) " +
    $"VALUES ('{orderCodeTB.Text.ToLower()}', '{orderNameRTB.Text.ToLower()}', 5)");
foreach (DataGridViewRow row in eventsDGV.Rows)
{
    ....
}
Блок кода 2 (Публичный статический класс Data)
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public static void Query(string query)
{
    using (Db database = new Db())
    {
        database.OpenConnection();
        NpgsqlCommand cmd = new NpgsqlCommand(query, database.GetConnection());
        try
        {
            cmd.ExecuteNonQuery();
        }
        catch (Exception)
        {
            MessageBox.Show(query);
        }
    }
}
После обработки ошибки в try catch в методе public static void Query(string query) выполнение кода в классе AddAsignment продолжается дальше (в блоке кода 1) и переходит к foreach, чего бы хотелось избежать и остановить выполнение сразу после вывода MessageBox для так скажем постоянного дебага неправильного запроса.
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
16.04.2024, 16:04
Ответы с готовыми решениями:

Остановка и возобновление выполнения кода
Здравствуйте! Подскажите пожалуйста, а может посоветуйте или даже дадите ссылку. Дело в том что есть событие нажатия на кнопку,...

Остановка выполнения кода программы на N сек.
Вообщемс сабж. Например у меня программа выдает окошко,и вот надо условие,когда она выдала окно,прекращаем код программы на 8...

Остановка выполнения кода при немодальной форме
Приветствую. Существует проблема: При выполнении программы необходимо вызывать пользовательскую форму и останавливать выполнение до тех...

12
2283 / 1599 / 400
Регистрация: 26.06.2017
Сообщений: 4,739
Записей в блоге: 1
16.04.2024, 16:18
Отдебажить всё не получится априори, т.к. БД будет постоянно меняться, код рефакториться и т.п. Поэтому чаще применяют не mbox, а какой нибудь логгер.
Если Вам надо остановить/приостановить работу при возникновении ошибки, то:
вариант 1 - оберните в try catch не код в методе Query, а во внешнем по отношению к нему.
вариант 2 - создайте событие в методе Query, которое обрабатывайте во внешнем коде.
0
0 / 0 / 0
Регистрация: 01.04.2024
Сообщений: 10
16.04.2024, 16:30  [ТС]
Мне нужно отдебажить лишь итоговый запрос, который будет отправляться в бд, то есть например увидеть, что в бд отправилось по итогу выполнения метода INSERT INTO orders(code, name, guarantor_id) VALUES ('121.121.121', 'Тестовый приказ', 5);

Если оборачивать во внешнем, то это нужно будет каждый Query оборачивать, и при этом я не смогу передавать в mbox тот string query, который я задавал в Data.Query(). Для этого придётся постоянно создавать переменную, а если обернуть в классе Data cmd.ExecuteNonQuery(), то все Query() будут проходить через него и смогут выводить запрос, но код продолжает выполняться
0
2283 / 1599 / 400
Регистрация: 26.06.2017
Сообщений: 4,739
Записей в блоге: 1
17.04.2024, 08:54
Тогда вариант 2
0
176 / 74 / 27
Регистрация: 10.11.2023
Сообщений: 199
17.04.2024, 12:01
Цитата Сообщение от Klaudis Посмотреть сообщение
после вывода ошибочного запроса
Пусть метод Query выполняет свои задачи, анализировать исключения лучше в другом месте.
Цитата Сообщение от Klaudis Посмотреть сообщение
Если оборачивать во внешнем, то это нужно будет каждый Query оборачивать, и при этом я не смогу передавать в mbox тот string query,
Сделайте проброс исключения в Query

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public static void Query(string query) {
  using(Db database = new Db()) {
    database.OpenConnection();
    NpgsqlCommand cmd = new NpgsqlCommand(query, database.GetConnection());
    try {
      cmd.ExecuteNonQuery();
    } catch (Exception ex) {
      // расширяем исключение 
      // добавив информацию о запросе 
      // в словарь Data
     if (ex is SqlException)
      ex.Data.Add("Query", query);
      throw;
    } finally {
      // закрываем если подключение открыто 
      database.CloseConnection();
    }
  }
}
и перехватывайте в Блоке 1
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
try {
  Data.Query($"INSERT INTO orders(code, name, guarantor_id) " +
    $ "VALUES ('{orderCodeTB.Text.ToLower()}', '{orderNameRTB.Text.ToLower()}', 5)");
  foreach(DataGridViewRow row in eventsDGV.Rows) {
    ....
  }
} catch (SqlException ex) {
  var query = ex.Data["Query"];
  MessageBox.Show(query);
 
} catch (Exception ex) {
  MessageBox.Show(ex.Message);
}
Если Query бросит исключение, то в цикл foreach вы не попадете.
0
2283 / 1599 / 400
Регистрация: 26.06.2017
Сообщений: 4,739
Записей в блоге: 1
17.04.2024, 12:20
Цитата Сообщение от Klaudis Посмотреть сообщение
Если оборачивать во внешнем, то это нужно будет каждый Query оборачивать,
Цитата Сообщение от ZeroKara Посмотреть сообщение
и перехватывайте в Блоке 1
Так ТС и говорит о том, что ему так не удобно делать.
0
176 / 74 / 27
Регистрация: 10.11.2023
Сообщений: 199
17.04.2024, 12:35
Не увидел где там ТСу неудобно.
Перехватывать исключения можно и глобально, необязательно в Блоке 1
и не нужно каждый Query оборачивать try catch.

string query получено. Код дальше не выполняется.
Метод Query выполняет свою задачу
а не анализирует исключение.
0
2283 / 1599 / 400
Регистрация: 26.06.2017
Сообщений: 4,739
Записей в блоге: 1
17.04.2024, 13:08
Вариант с событием.
Класс Data
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class Data
{
  public static Action<string> errorInData;
 
  public static void Query(string query)
  {
      using (Db database = new Db()) // Не понятно зачем каждый раз пересоздавать Db, особенно в статичном методе!!!
      {
        database.OpenConnection();
        NpgsqlCommand cmd = new NpgsqlCommand(query, database.GetConnection());
        try
        {
          cmd.ExecuteNonQuery();
        }
        catch (Exception)
        {
          errorInData?.Invoke(query);
        }
    }
  }

Где-то во внешнем коде
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//Сначала подпишем
Data.errorInData = PrintError;
 
private void PrintError(string text)
{
   MessageBox.Show(text);
}
// а потом используем
Data.Query($"INSERT INTO orders(code, name, guarantor_id) " +
    $"VALUES ('{orderCodeTB.Text.ToLower()}', '{orderNameRTB.Text.ToLower()}', 5)");
foreach (DataGridViewRow row in eventsDGV.Rows)
{
    ....
}
0
0 / 0 / 0
Регистрация: 01.04.2024
Сообщений: 10
19.04.2024, 08:37  [ТС]
Цитата Сообщение от Uswer Посмотреть сообщение
Вариант с событием.
Вариант с событием к сожалению не сработал, код продолжает выполняться после запроса с ошибкой. Насчет пересоздания, то там Disposable класс с CloseConnection() в виде Dispose(). Если это неверный подход, то приветствую правильный подход, исправлю

Цитата Сообщение от ZeroKara Посмотреть сообщение
Перехватывать исключения можно и глобально, необязательно в Блоке 1
и не нужно каждый Query оборачивать try catch.
Не разбираюсь, что значит перехватить "глобально", чтобы если в этом классе было 50 методов с запросом, они все могли идти по одному пути try catch'а, кроме как обрабатывать в самом классе Data, а не внешнем. Буду рад увидеть представление, потому что этот вариант, насколько я понял, работает при едином вызове, а вот если таких вызовов десятки, как поступить, чтоб не оборачивать каждый?
0
176 / 74 / 27
Регистрация: 10.11.2023
Сообщений: 199
19.04.2024, 09:03
Лучший ответ Сообщение было отмечено Klaudis как решение

Решение

Можно возвращать true false из Query или коды ошибок

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
     try
     {
         cmd.ExecuteNonQuery();
        return true; //  успешный успех 
 
     }
     catch (Exception ex)
     {
           MessageBox.Show(ex.Message + "  " + query);
         return false; // всё пропало 
     }
  
     finally
     {
         // закрываем если подключение открыто 
      database.CloseConnection();
         }
и проверяйте

C#
1
2
3
4
5
6
7
    if( Data.Query($"  .... "))
     {     
        foreach (DataGridViewRow row in eventsDGV.Rows)
       {
            ....
         }
     }
Добавлено через 5 минут
И не стоит игнорировать исключение .
Цитата Сообщение от Klaudis Посмотреть сообщение
C#
1
2
3
4
catch (Exception)
        {
            MessageBox.Show(query);
        }
1
0 / 0 / 0
Регистрация: 01.04.2024
Сообщений: 10
19.04.2024, 09:05  [ТС]
Точно, вариант оказался довольно простым в исполнении, спасибо!
0
176 / 74 / 27
Регистрация: 10.11.2023
Сообщений: 199
19.04.2024, 09:13
Цитата Сообщение от Klaudis Посмотреть сообщение
что значит перехватить "глобально",
https://stackoverflow.com/ques... n-handling
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
public static void Main()
{
    AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(MyHandler);
 
    // start main thread here
}
 
static void MyHandler(object sender, UnhandledExceptionEventArgs args) 
{
    Exception e = (Exception) args.ExceptionObject;
    Console.WriteLine("MyHandler caught : " + e.Message);
}
0
0 / 0 / 0
Регистрация: 07.04.2021
Сообщений: 5
10.02.2026, 13:44
Я поместил выполнение нескольких QUERY
в do while если срабатывает catch то break
вот типо такого, не знаю может это неправильно, но нужную остановку он мне делает.

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
                  
                    connection.Open();
                    DO
                    {
                        using (SqlCommand da = new SqlCommand("EXEC [p_KB_CLIENT]", connection))
                        {
                            try
                            {
                                da.ExecuteNonQuery();
                            }
                            catch (Exception ex)
                            {
                                MessageBox.Show(ex.Message, "Ошибка! p_KB_CLIENT", MessageBoxButtons.OK, MessageBoxIcon.Error);
                                connection.Close();
                                break;
                            }
                            /*данный финали для получения Exception, следующий блок Query должен не выполниться из-за закрытого  connection*/
                            finally
                            {
                                connection.Close();
                            }
                        }
 
                        using (SqlCommand da = new SqlCommand("EXEC [p_KB_GD_RAH]", connection))
                        {
                            try
                            {
                                da.ExecuteNonQuery();
                                MessageBox.Show("успешный успех p_KB_GD_RAH");// для проверки
                            }
                            catch (Exception ex)
                            {
                                MessageBox.Show(ex.Message, "Ошибка! p_KB_GD_RAH", MessageBoxButtons.OK, MessageBoxIcon.Error);
                                connection.Close();
                                break;
                            }
                        }
                        using (SqlCommand da = new SqlCommand("EXEC [p_KB_XLS_GOP]", connection))
                        {
                            try
                            {
                                da.ExecuteNonQuery();
                                MessageBox.Show("успешный успех p_KB_XLS_GOP"); // для проверки
                            }
                            catch (Exception ex)
                            {
                                MessageBox.Show(ex.Message, "Ошибка! p_KB_XLS_GOP", MessageBoxButtons.OK, MessageBoxIcon.Error);
                                break;
                            }
                            finally
                            {
                                connection.Close();
                            }
                        }
 
                        MessageBox.Show("Информация успешно импортирована в хозяйственные операции");
                        HOZoper form2 = new HOZoper(connection, 1); // 1 - XLS, 2 - DBF, 3 - XML, 4 - TXT
                        form2.ShowDialog();
 
                    } WHILE(false);
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
10.02.2026, 13:44
Помогаю со студенческими работами здесь

Остановка выполнения кода и ожидание реакции пользователя
Привет! Такой вопрос. У меня есть некоторая функция Foo1, которая выполняется при возникновении Event1. Во время выполнения этой...

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

Остановка программы, после выполнения условия
Всем доброго времени суток!! Есть такой код программы: for (i = 0; i &lt; 3; i++) { for (j = 0; j &lt; 3;...

Остановка сразу после выполнения system()
вошм пишу прогу с OGL решил попробовать вывести кое какие данные в CMD но трабла в том что при вызове system() работа программы не...

Остановка после выполнения функции stop
почему, когда запускаешь start(), циклит start() stop() start() stop() и т.д.. он же должен останавливаться после выполнения функции stop()...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Новые блоги и статьи
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru