Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.10.03;
Скачать: CL | DM;

Вниз

Перехват ошибок IB   Найти похожие ветки 

 
REA   (2004-09-02 15:55) [0]

Вопрос наверно очень старый, но в FAQ не нашел: как мне перехватить сообщение IB о нарушении ключа (Key violation)?
Где взять коды ошибок? Как сделать универсальный перехват для разных версий IB и Firebird?


 
HSolo ©   (2004-09-02 16:04) [1]

>как мне перехватить сообщение IB о нарушении ключа (Key violation)?
Как и любое другое исключение:
try - except - end
Application.OnException

>Где взять коды ошибок
http://ibase.ru/ib6.htm#doc - Language Reference


 
REA   (2004-09-02 16:37) [2]

>try - except - end
>Application.OnException

Не самый лучший подход на мой взгляд, хотя возможно другой не подойдет.
Логичнее бы перехватить OnPostError например, но
желательно сделать единообразную обработку для многих таблиц.
Вместо указания названий таблиц и полей нужно вывести "Значение поля "Некое поле или комбинация полей по-русски" повторяется".

Примерчика нету? Сам то я сделаю конечно, но готовое проще испльзовать :)


 
HSolo ©   (2004-09-02 16:53) [3]

Так "единообразная обработка для многих таблиц" как раз хорошо ложится на Application.OnException. Впрочем, хозяин - барин :)
Примера для OnPostError нету, у меня все ловится в Application.OnException


 
REA   (2004-09-02 17:05) [4]

>у меня все ловится в Application.OnException

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


 
HSolo ©   (2004-09-02 17:38) [5]

Пожалуйста, только у меня все под FIBPlus заточено. Схема такая:
...
Application.OnException := MyAppException;
...
procedure TDM.MyAppException(Sender: TObject; E: Exception);
begin
RusMessages.ShowException(E);
end;

А RusMessages - это экземпляр моего класса-переводчика сообщений:

unit IBRusFIB;

interface

uses Windows, SysUtils, Classes, DB, FIB;

type
TFIBRusMessages = class(TStringList)
 private
       fShowOrigMessage: boolean;
       fAppHandle: HWND;
       function GetRussianMessage(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;
       property MyAppHandle: HWND read fAppHandle write fAppHandle;
end;

implementation

constructor TFIBRusMessages.Create(aFileName: string);
begin
inherited Create;
fShowOrigMessage := true;
try
  LoadFromFile(aFileName);
  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;
begin
 if (E is EFIBError) or (E is EFIBInterBaseError) or (E is EFIBClientError)
 then
 with EFIBError(E) do
 begin
 //особый случай для пользовательских исключений
 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 TFIBRusMessages.ShowException(var E: Exception);
begin
if E is EDatabaseError
  then TranslateDBException(EDatabaseError(E));
MessageBox(fAppHandle, PChar(E.message), PChar("Внимание!"), MB_OK or MB_ICONWARNING);
end;

end.


 
HSolo ©   (2004-09-02 17:43) [6]

Создание объекта:
RusMessages := TFIBRusMessages.Create(ExtractFilePath(ParamStr(0))+"fib_rus.txt");
RusMessages.ShowOrigMessage := true;
RusMessages.MyAppHandle := Application.Handle;

fib_rus.txt - файл с кодами ошибок и их переводом, вот кусок:

14=Не указана база данных. Обратитесь к системному администратору
15=База данных недоступна. Обратитесь к системному администратору
-551=Не хватает прав для выполнения операции
-902=Не удалось подключиться к базе данных. Возможно, ошибка в пароле или имени пользователя. Обратитесь к системному администратору


 
REA   (2004-09-03 10:19) [7]

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


 
HSolo ©   (2004-09-03 11:31) [8]

Это сложнее. Придется, наверное, анализировать сообщение от сервера, вытаскивать из него некие ключевые слова (напр., имена полей) и подставлять вместо них термины, понятные пользователю (скажем, брать в базе описания полей, или сделать свой словарь...)
Просто у меня вышеописанное - вторая линия обороны :) Первая - это экранные формы ввода/редактирования. Там DB-контролов вообще нет, и там делается куча проверок, чтобы не отправлять на сервер заведомую галиматью. Плюс еще сервер проверяет, что ему прислали, и если что не так - сообщает об этом по-русски :) До сих пор мне этого хватало (может, просто везло?)


 
REA   (2004-09-06 10:27) [9]

>чтобы не отправлять на сервер заведомую галиматью

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

>Плюс еще сервер проверяет, что ему прислали, и если что не так - сообщает об этом по-русски :)

А это как?


 
jack128 ©   (2004-09-06 10:32) [10]

REA   (06.09.04 10:27) [9]
А это как?

пользовательские EXCEPTION"ы генерирует, видимо..


 
HSolo ©   (2004-09-06 11:41) [11]

>пользовательские EXCEPTION"ы генерирует, видимо
Именно так



Страницы: 1 вся ветка

Текущий архив: 2004.10.03;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.027 c
4-1093435836
Cat
2004-08-25 16:10
2004.10.03
Работа с портом LPT


3-1094060707
Maverick
2004-09-01 21:45
2004.10.03
ODAC


8-1088677157
leonidus
2004-07-01 14:19
2004.10.03
Как извлечь информацию из ID тэгов mp3-файлов


14-1095165222
infom
2004-09-14 16:33
2004.10.03
Что за проблемы с DevExpress ?


14-1095319510
VID
2004-09-16 11:25
2004.10.03
Зацените, плиз...