ODBC ошибка - закрыть приложение в тихую

Clarion, Clarion 7

Модератор: Дед Пахом

Правила форума
При написании вопроса или обсуждении проблемы, не забывайте указывать версию Clarion который Вы используете.
А так же пользуйтесь спец. тегами при вставке исходников!!!
Ответить
gopstop2007
✯ Ветеран ✯
Сообщения: 1702
Зарегистрирован: 25 Март 2009, 21:55
Благодарил (а): 9 раз
Поблагодарили: 4 раза

ODBC ошибка - закрыть приложение в тихую

Сообщение gopstop2007 »

При работе с удаленным сервером, редко, может произойти обрыв соединения (моргнул свет - перезагрузка роутера и т.п.). После которого, начинают вываливаться ошибки, программа не видит обрыв соединения и продолжает коннектиться к серверу.
Не подскажите или может у кого то есть готовое решение, как сразу закрыть программу, не закрывая ...надцадь сообщений об ошибке, или как правильно сделать реконект?
Спасибо за внимание
“Есть всего 2 типа языков: те, на которые все жалуются и те, которыми никто не пользуется.” — Бьерн Страуструп
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 7322
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 13 раз
Поблагодарили: 48 раз

ODBC ошибка - закрыть приложение в тихую

Сообщение Игорь Столяров »

gopstop2007 писал(а): 17 Август 2019, 8:45как сразу закрыть программу, не закрывая ...надцадь сообщений об ошибке
HALT ? ;)
За теми кто отстал - не возвращаться. (С) Кодекс
gopstop2007
✯ Ветеран ✯
Сообщения: 1702
Зарегистрирован: 25 Март 2009, 21:55
Благодарил (а): 9 раз
Поблагодарили: 4 раза

ODBC ошибка - закрыть приложение в тихую

Сообщение gopstop2007 »

Игорь Столяров писал(а): 17 Август 2019, 8:47HALT ? ;)
Вы предлагаете пробежаться по всему коду multi-dll приложения и прописать везде HALT :( , а нет более "красивого" решения? :)
“Есть всего 2 типа языков: те, на которые все жалуются и те, которыми никто не пользуется.” — Бьерн Страуструп
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 7322
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 13 раз
Поблагодарили: 48 раз

ODBC ошибка - закрыть приложение в тихую

Сообщение Игорь Столяров »

gopstop2007 писал(а): 17 Август 2019, 8:53Вы предлагаете пробежаться по всему коду multi-dll приложения и прописать везде HALT
Нет. Я предлагаю все запросы к удалённой БД выполнять через одну процедуру-коннектор, в которой будет проверка
подключения к БД перед выполнением запроса и выгрузка приложения в случае его обрыва.
За теми кто отстал - не возвращаться. (С) Кодекс
gopstop2007
✯ Ветеран ✯
Сообщения: 1702
Зарегистрирован: 25 Март 2009, 21:55
Благодарил (а): 9 раз
Поблагодарили: 4 раза

ODBC ошибка - закрыть приложение в тихую

Сообщение gopstop2007 »

я не везде использую конструкцию file{PROP:SQL}
например для

Код: Выделить всё

select ... from ... where
используется

Код: Выделить всё

LoadQueueFromSQL('select ... from ... where',Queue)
будет ли коннектор срабатывать?
“Есть всего 2 типа языков: те, на которые все жалуются и те, которыми никто не пользуется.” — Бьерн Страуструп
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 7322
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 13 раз
Поблагодарили: 48 раз

ODBC ошибка - закрыть приложение в тихую

Сообщение Игорь Столяров »

А почему нет ? Если Вы завернёте вызов:

Код: Выделить всё

CheckAndLoadSQL Procedure('select ... from ... where',Queue)
  Code
  
  If ПРОВЕРКА ДОСТУПНОСТИ ИСТОЧНИКА
     LoadQueueFromSQL('select ... from ... where',Queue)  
  else
     HALT('У НАС ПРОБЛЕМЫ С ПОДКЛЮЧЕНИЕМ - ВЫРУБАЕМ ПРОГРАММУ !')
  end   
и вместо LoadQueueFromSQL будите везде вызывать CheckAndLoadSQL - то какие могут быть проблемы в принципе ?
За теми кто отстал - не возвращаться. (С) Кодекс
kreator
✯ Ветеран ✯
Сообщения: 4960
Зарегистрирован: 28 Май 2009, 15:54
Откуда: Москва
Благодарил (а): 6 раз
Поблагодарили: 19 раз

ODBC ошибка - закрыть приложение в тихую

Сообщение kreator »

gopstop2007, посмотрите вот сюда - https://clarionhub.com/t/handling-disco ... halts/1591 или https://clarionhub.com/t/errorcode-90-c ... ction/2561. Мне тоже нужно будет совсем в недалёком будущем, но скорее как временное решение. Руки пока не дошли.
We are hard at work… for you. :)
Yufil
Ветеран движения
Сообщения: 1277
Зарегистрирован: 16 Май 2006, 14:34
Контактная информация:

ODBC ошибка - закрыть приложение в тихую

Сообщение Yufil »

А я где-то здесь писал. Перехватываю Message() с заменой на свою функцию, смотрю сообщение об ошибке и ищу в тексте сообщения определённый фрагмент (туда дублируется сообщение сервера ) и код FileErrorCode(). Если есть в тексте сообщения - HALT ( точнее, вопрос оператору и варианты - HALT/ рестарт программы и HALT/попытка продолжить работу ), если нет - снимаем перехват с Message и выводим повторно текст сообщения. Ещё пользовал метод Throw, но там была другая идея - выдача разумного сообщения при нарушении ссылочной целостности ( выводится сообщение примерно такого вида "Введено недопустимое или дублирующее значение - нарушена уникальность записи-Запись используется в таблице "Персонал" ' ), может быть, и здесь можно попробовать.

К сожалению, за давностью лет ...Старик Альцгеймер... Но поищу...
Yufil
Ветеран движения
Сообщения: 1277
Зарегистрирован: 16 Май 2006, 14:34
Контактная информация:

ODBC ошибка - закрыть приложение в тихую

Сообщение Yufil »

Ага, нашёл кое-что...
Вот перехват Message

! LocalMessage FUNCTION(STRING,<STRING>,<STRING>,<STRING>,UNSIGNED=0,UNSIGNED=0),UNSIGNED,PROC !Перехват Message

Код: Выделить всё

LocalMessage         PROCEDURE  (STRING Msg,<STRING Header>,<STRING Icon>,<STRING Buttons>,UNSIGNED Default,UNSIGNED Modal) ! Declare Procedure
! Before Embed Point: %DataSection) DESC(Data Section) ARG()
SaveErr   Group,Pre(SE)
Error     Cstring(300)
ErrorCode Long
FileError Cstring(1000)
FileErrorCode Long
          End

ErrLevel  Long,Static,Thread  ! Чтобы не отрабатывать повторную ошибку
FstrCount Long
Q         Queue,Pre(Q)
N         Long
          End
! After Embed Point: %DataSection) DESC(Data Section) ARG()
  CODE
! Before Embed Point: %ProcessedCode) DESC(Processed Code) ARG()
!       Ret#=Message(Msg,Header,Icon,Buttons,Default,Modal)
!       Return Ret#
       Se:ErrorCode = ErrorCode()
       Se:Error = Error()
       Se:FileErrorCode = FileErrorCode()
       Se:FileError = FileError()
       ! Переключаемся на стандартный Message
       System{Prop:MessageHook}=0
       ! Выдаём стандартное сообщение
       Ret#=Message(Msg,Header,Icon,Buttons,Default,Modal)
       !SetErrorCode(0)
       Add(Q) ! Чтобы ErrorCode сбросить в 0
       !SetPath(LongPath())
       N# = Records(Config)
       If ErrorCode() ! Or Inlist(ErrorCode(),90,47)
          Case Message('Нет доступа к серверу или базе данных .|' & |
             Choose(Se:Error & Se:FileError<>'', ' Ошибка ' & Se:Error & ' ' & Se:FileError,''),  |
             'Внимание!',Icon:Question,'Перезапуск|Завершить|Дальше')
          Of 1
            Do RunCommand
          Of 2
            Halt(0)
          Of 3
          END
       End
       !etErrorCode(Se:ErrorCode)
       System{Prop:MessageHook} = Address(LocalMessage)
       Return Ret#
Запускается командой

Код: Выделить всё

System{Prop:MessageHook} = Address(LocalMessage)
После этого если ErrorCode() = 90 и FileErrorCode() > 0 - то облом...
А теперь насчёт Throw

Декларируется функция

Код: Выделить всё

FileThrow              FUNCTION(*FIleManager Fm,<String FIleName>),Long   !Вывод сообщений об ошибке

Код: Выделить всё

FileThrow            PROCEDURE  (*FIleManager Fm,<String FileName>) ! Declare Procedure
! Before Embed Point: %DataSection) DESC(Data Section) ARG()
Loc:FileName         Cstring(100)
Loc:FileError        Cstring(500)
Loc:Info             Cstring(100)

A                    Any
Loc:Pos              Long
TextGroup            Group
                      String('unique key|Нарушена уникальность записи')
                      String('table reference|Запись используется в другой таблице БД')
                     End
Loc:Msg              Cstring(100)
! After Embed Point: %DataSection) DESC(Data Section) ARG()
  CODE
! Before Embed Point: %ProcessedCode) DESC(Processed Code) ARG()
    Loc:FileError=Lower(FileError())
    Loop Row# =1 to 1000
      A &= What(TextGroup,Row#)
      If A &= Null
        Loc:Pos = 0
        Break
      End
      Loc:Msg = A
      Loc:Pos = Instring('|',Loc:Msg,1,1)
      If Loc:Pos>0
        If Instring(Loc:Msg[1 : Loc:Pos-1], Loc:FileError,1,1)
          Break
        End
      End
    End
    If Omitted(2)
      GlobalErrors.SetFile(Fm.GetName())
      Loc:FileName = Fm.GetName()
    Else
      GlobalErrors.SetFile(FileName)
      Loc:FileName = FileName
    End
    Case FM.GetError()
    Of Msg:DeleteFailed
      Case FileErrorCode()
      Of 23000
        Message('Ошибка при удалении строки ' |
         & 'из справочника "' & Loc:FileName & '"|' |
         & Choose(Loc:Pos>0, Loc:Msg[Loc:Pos+1 : Len(Loc:Msg)],'') & '|' |
         |!& 'Сообщение сервера:' & FileError()
         ,'Ошибка удаления записи',Icon:Exclamation)
        Return Level:Notify
      End
    Of Msg:AddFailed Orof Msg:PutFailed
      Case FileErrorCode()
      Of 23000
        Message('Введено дублирующее или недопустимое значение ' |
         & 'для справочника "' & Loc:FileName & '"|' |
         & Choose(Loc:Pos>0, Loc:Msg[Loc:Pos+1 : Len(Loc:Msg)],'') & '|' |
         |!& 'Сообщение сервера:' & FileError()
         ,'Ошибка создания записи',Icon:Exclamation)
        Return Level:Notify
      Else
        Message('Введено дублирующее или недопустимое значение ' |
         & 'для справочника "' & Loc:FileName & '"|' |
         & Choose(Loc:Pos>0, Loc:Msg[Loc:Pos+1 : Len(Loc:Msg)],'') & '|' |
         |!& 'Сообщение сервера:' & FileError()
         ,'Ошибка сохранения записи',Icon:Exclamation)
        Return Level:Notify
      End
    End
    !Stop('FileError=' & FileError() & ' FileErrorCode=' & FileErrorCode())
    RETURN GlobalErrors.ThrowMessage(Fm.GetError(),FileName)
Для таблиц вносится вставка для метода Throw ( пример для таблицы VID_KONTR )

Код: Выделить всё

Hide:Access:VID_KONTR.Throw PROCEDURE
ReturnValue          BYTE,AUTO

  CODE
      Return Self.FileThrow('Виды контроля') ! *** Наша вставка *** 
  ReturnValue = PARENT.Throw()
  RETURN ReturnValue
Коды ошибок для MS SQL, для других серверов будет по-другому.
После этого сообщение принимает намного более содержательный вид
Yufil
Ветеран движения
Сообщения: 1277
Зарегистрирован: 16 Май 2006, 14:34
Контактная информация:

ODBC ошибка - закрыть приложение в тихую

Сообщение Yufil »

gopstop2007 писал(а): 17 Август 2019, 9:20 я не везде использую конструкцию file{PROP:SQL}
например для

Код: Выделить всё

select ... from ... where
используется

Код: Выделить всё

LoadQueueFromSQL('select ... from ... where',Queue)
будет ли коннектор срабатывать?
LoadQueueFromSQL содержит самые обычные операции с кларионовскими БД - Open, Close, File{Prop:SQL}, Next. После каждой добавить адекватную проверку и обработку ErrorCode() - обычно равно 90, FileErrorCode и FileError. Или просто вывести Message, как указано выше...
gopstop2007
✯ Ветеран ✯
Сообщения: 1702
Зарегистрирован: 25 Март 2009, 21:55
Благодарил (а): 9 раз
Поблагодарили: 4 раза

ODBC ошибка - закрыть приложение в тихую

Сообщение gopstop2007 »

Yufil писал(а): 17 Август 2019, 22:24 Ага, нашёл кое-что...
Вот перехват Message
Спасибо большое, интересное решение!
“Есть всего 2 типа языков: те, на которые все жалуются и те, которыми никто не пользуется.” — Бьерн Страуструп
gopstop2007
✯ Ветеран ✯
Сообщения: 1702
Зарегистрирован: 25 Март 2009, 21:55
Благодарил (а): 9 раз
Поблагодарили: 4 раза

ODBC ошибка - закрыть приложение в тихую

Сообщение gopstop2007 »

kreator писал(а): 17 Август 2019, 13:20gopstop2007, посмотрите вот сюда - https://clarionhub.com/t/handling-disco ... halts/1591 или https://clarionhub.com/t/errorcode-90-c ... ction/2561. Мне тоже нужно будет совсем в недалёком будущем, но скорее как временное решение. Руки пока не дошли.
Спасибо kreator, там пишут, что не всегда помогает :(
“Есть всего 2 типа языков: те, на которые все жалуются и те, которыми никто не пользуется.” — Бьерн Страуструп
kreator
✯ Ветеран ✯
Сообщения: 4960
Зарегистрирован: 28 Май 2009, 15:54
Откуда: Москва
Благодарил (а): 6 раз
Поблагодарили: 19 раз

ODBC ошибка - закрыть приложение в тихую

Сообщение kreator »

gopstop2007 писал(а): 18 Август 2019, 15:36 Спасибо kreator, там пишут, что не всегда помогает
Какое решение не помогает? По-моему, решение ДП то, что надо.
Забыл в предыдущем своём посте заметить, что наш планшетный модуль (написанный в основном мной) похоже идёт в урну. На конец 2019 года он не удовлетворяет требованиям. Клиент просит немного доработать и начать смотреть на смартфоны. Поэтому тратить время на "доработать" не очень хочется.
We are hard at work… for you. :)
gopstop2007
✯ Ветеран ✯
Сообщения: 1702
Зарегистрирован: 25 Март 2009, 21:55
Благодарил (а): 9 раз
Поблагодарили: 4 раза

ODBC ошибка - закрыть приложение в тихую

Сообщение gopstop2007 »

kreator писал(а): 18 Август 2019, 16:21Какое решение не помогает? По-моему, решение ДП то, что надо.
Насчет ДП и не сомневаюсь, я с ним уже связался :)
kreator писал(а): 18 Август 2019, 16:21 Забыл в предыдущем своём посте заметить, что наш планшетный модуль (написанный в основном мной) похоже идёт в урну. На конец 2019 года он не удовлетворяет требованиям. Клиент просит немного доработать и начать смотреть на смартфоны. Поэтому тратить время на "доработать" не очень хочется.
У меня похожий результат :( Советую смотреть в сторону React Native.
“Есть всего 2 типа языков: те, на которые все жалуются и те, которыми никто не пользуется.” — Бьерн Страуструп
kreator
✯ Ветеран ✯
Сообщения: 4960
Зарегистрирован: 28 Май 2009, 15:54
Откуда: Москва
Благодарил (а): 6 раз
Поблагодарили: 19 раз

ODBC ошибка - закрыть приложение в тихую

Сообщение kreator »

gopstop2007 писал(а): 18 Август 2019, 16:29У меня похожий результат Советую смотреть в сторону React Native.
Велосипедистов не ждать? На чистом Реакте попробовать?
We are hard at work… for you. :)
Ответить