Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2004.10.03;
Скачать: [xml.tar.bz2];

Вниз

Перехват ошибок 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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.48 MB
Время: 0.033 c
3-1094545933
Virgo
2004-09-07 12:32
2004.10.03
Помогите разобраться с ODAC компонентами


3-1094036904
Term
2004-09-01 15:08
2004.10.03
Как отобразить содержимое Memo-поля в DBGrid ???


14-1095136210
Tiam
2004-09-14 08:30
2004.10.03
Что вы об этом думаете?


14-1093716915
ИМХО
2004-08-28 22:15
2004.10.03
ЛЧ 2004/05


6-1090973055
Лев Ландау
2004-07-28 04:04
2004.10.03
Как вытащить текущее значение URL из TWebBrowser-a?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский