Перехоплення помилок IB
Питання напевно дуже старе, але у FAQ не знайшло: як мені перехопити повідомлення IB про порушення ключа (Key violation)? Де взяти коди помилок? Як зробити універсальний перехоплення для різних версій IB та Firebird?
Як мені перехопити повідомлення IB про порушення ключа (Key violation)? Як і будь-який інший виняток: try - except - end Application.OnException
>Де взяти коди помилок http://ibase.ru/ib6.htm#doc - Language Reference
>try - except - end >Application.OnException
Не найкращий підхід на мій погляд, хоча можливо інший не підійде. Логічніше б перехопити OnPostError наприклад, але бажано зробити однакову обробку для багатьох таблиць. Замість вказівки назв таблиць та полів потрібно вивести "Значення поля "Деяке поле або комбінація полів по-українськи" повторюється".
Прикладника немає? Сам то я зроблю звичайно, але готове простіше використовувати :)
Так "одноподібна обробка для багатьох таблиць" добре лягає на Application.OnException. Втім, господар - пан :) Прикладу для OnPostError немає, у мене все ловиться в Application.OnException
>у мене все ловиться в Application.OnException
ну покажи плиз як ловиш те (там особливої різниці нема на чому ловити) - може знадобитися.
Будь ласка, тільки у мене все під FIBPlus ув'язнено. Схема така: . Application.OnException := MyAppException; . procedure TDM.MyAppException(Sender: TObject; E: Exception); begin RusMessages.ShowException(E); end;
А RusMessages - це екземпляр мого класу-перекладача повідомлень:
uses Windows, SysUtils, Classes, DB, FIB;
type TFIBRusMessages = class(TStringList) private fShowOrigMessage: boolean; fAppHandle: HWND; functionGetRussianMessage(aSQLCode: integer): string; //службова: дістати текст помилки за SQL code та IB Error code //якщо не знайшла - поверне sUnknownError procedure TranslateDBException(var E: EDatabaseError); //Якщо розпізнала виняток E, то перекладає //повідомлення E.message українською (із збереженням тексту оригіналу) public constructor Create(aFileName: string); procedure ShowException(var E: Exception); //Намагається перекласти E.message українською, після чого виводить E.message property ShowOrigMessage: boolean read fShowOrigMessage write fShowOrigMessage; properties MyAppHandle: HWND read fAppHandle write fAppHandle; end;
constructor TFIBRusMessages.Create (aFileName: string); except MessageBox(0, PChar("Файл "+aFileName+" не знайдений"), PChar("Помилка"), MB_OK or MB_ICONERROR); end; end;
function TFIBRusMessages.GetRussianMessage(aSQLCode: integer): string; const sUnknownError = "Невідома помилка, зверніться до програміста"; var s: string; begin s := IntToStr( aSQLCode); // + "+" + IntToStr(aIBErrorCode); Result := Values[s]; if Result = "" then Result := sUnknownError; end;
procedure TFIBRusMessages.TranslateDBException(var E: EDatabaseError); const cServer = chr(13)+chr(10)+chr(13)+chr(10)+"Оригінал повідомлення від сервера:"+chr( 13)+chr(10)+"%s"+chr(13)+chr(10)+"SQL code: %d"; var s: string; ts: TStringList; 1>//особливий випадок для винятків користувача if SQLCode = -836 then begin s := message; ts:= TStringList.Create; try ts.Text :=message; s:=ts.Strings[ts.count-1]; finally ts.Free; end; end else s := GetRussianMessage(SQLCode); if fShowOrigMessage then s := s + cServer; Message:=Format(s,[Message, SQLCode]); end; end;
procedure TFIBRus Messages. "Увага!"), MB_OK or MB_ICONWARNING); end;
Створення об'єкта: RusMessages := TFIBRusMessages.Create(ExtractFilePath(ParamStr(0))+"fib_rus.txt"); RusMessages.ShowOrigMessage := true; RusMessages.MyAppHandle := Application.
fib_ukr.txt - файл з кодами помилок та їх перекладом, ось шматок:
14=Не вказано базу даних. Зверніться до системного адміністратора 15=База даних недоступна. Зверніться до системного адміністратора -551=Не вистачає прав для виконання операції -902=Не вдалося підключитися до бази даних. Можливо, помилка в паролі чи імені користувача. Зверніться до системного адміністратора
Дякую, але тут ще переслідується інша мета. Просто перекласти повідомлення на українську мову можна і заміною msg файлу, а ось зробити, щоб вони стали зрозумілі користувачеві, треба попрацювати - потрібно видавати описи полів, а не їх назви і т.п. Як би це зробити?
Це складніше. Доведеться, напевно, аналізувати повідомлення від сервера, витягувати з нього якісь ключові слова (напр., імена полів) і підставляти замість них терміни, зрозумілі користувачеві (скажімо, брати в базі опису полів, або зробити свій словник.) Просто у мене вищеописане - друга лінія оборони:) Перша - це екранні форми введення/редагування. Там DB-контролів взагалі немає, і там робиться купа перевірок, щоб не надсилати на серверявну нісенітницю. Плюс ще сервер перевіряє, що йому прислали, і якщо що не так – повідомляє про це українською :) Досі мені цього вистачало (може, просто щастило?)
>щоб не відправляти на сервер явну нісенітницю
Можна перед вставкою напевно перевіряти, чи є вже таке ключове поле, але тоді треба знати список усіх помилок, які найімовірніше можуть виникнути на сервері.
>Плюс ще сервер перевіряє, що йому надіслали, і якщо що не так - повідомляє про це українською :)
REA (06.09.04 10:27) [9] А це як?користувацькі EXCEPTION"и генерує, мабуть.
>користувацькі EXCEPTION"и генерує, мабуть Саме так