Subject | Re: [IBO] How can I pass an FB custom exception ID & Text into my app? |
---|---|
Author | Helen Borrie |
Post date | 2008-07-03T00:29:15Z |
At 04:50 AM 3/07/2008, you wrote:
<< How can I pass an FB custom exception ID & Text into my app? >>
You can't "pass an FB custom exception ID & Text into my app" - unless you mean "How do I create one?" That's a DDL statement (CREATE EXCEPTION... ). You wouldn't normally create one in a production application, just as you wouldn't normally create a SP or trigger in a production application.
If you're talking about how to detect a custom exception when it occurs...IBO processes the array of exceptions (the read-only status vector) that comes across the wire from the server. You can look up the help for TIB_ErrorEvent to help understand the interpretation structure that IBO creates at the API level when the status vector is not empty. The object procedure's arguments are extracted from the EIB_ISCError object that is created when the IB_Session's OnError event occurs. The lowest-level exception, i.e. the last one in the error stack, is in Errorcodes[0].
There's no way to get at the symbolic name of the custom exception. The errorcodes are passed across as integers. For the system-defined exceptions, IBO has constants in IB_Header.pas that reflect the symbolic names exposed in iberror.h. For custom exceptions, i.e., the ones created in the database using CREATE EXCEPTION, the ERRCODE constant will be the RDB$EXCEPTIONS.RDB$.RDB$EXCEPTION_NUMBER that you can see if you query the system tables. If the WHEN ... handler in your trigger or SP raises your custom exception then this is the one that will be in Errorcodes[0].
Of course, IBO has no constants defined to represent your custom errorcodes, so a handy way to keep on top of these in your app would be to name constants for your RDB$EXCEPTION_NUMBER numbers, with symbols "matching" the identifiers in the database.
For example, suppose you had this definition in your DB:
CREATE EXCEPTION ROLE_EXISTS 'This person already has this role';
Here, in a BeforeInsert trigger, we want to intercept a specific uniqueness violation on 2 keys (NEW.person_id and NEW.role_id) during execution of a Before Insert trigger and pass a pinpointed exception message back to the client. (In Fb 2 you can override the declared message and do some wonderful things with custom exception message text!) Suppose that, in RDB$EXCEPTIONS, the RDB$EXCEPTION_NUMBER for this exception is 3...in your app, scoped inside in a custom error handler unit or perhaps in your datamodule, you might define a constant like this:
const
...
ROLE_EXISTS = 3;
...
Then your error handler can test Errorcodes[0] in the EIB_ISCError structure for ROLE_EXISTS. You might want to make it even more self-documenting by having each of the specific exceptions you want to handle with a client-side response, by created inherited custom EIB_ISCError classes for each one.
Not sure whether any of this addresses the question you intended to ask, though. ;-) If not, try to give more detail about what you want to do...
Helen
<< How can I pass an FB custom exception ID & Text into my app? >>
>I seem to recall seeing how to do this somewhere, but I have beenThere's a TI sheet at http://www.ibobjects.com/TechInfo.html - maybe that was it?
>unable to find it again.
You can't "pass an FB custom exception ID & Text into my app" - unless you mean "How do I create one?" That's a DDL statement (CREATE EXCEPTION... ). You wouldn't normally create one in a production application, just as you wouldn't normally create a SP or trigger in a production application.
If you're talking about how to detect a custom exception when it occurs...IBO processes the array of exceptions (the read-only status vector) that comes across the wire from the server. You can look up the help for TIB_ErrorEvent to help understand the interpretation structure that IBO creates at the API level when the status vector is not empty. The object procedure's arguments are extracted from the EIB_ISCError object that is created when the IB_Session's OnError event occurs. The lowest-level exception, i.e. the last one in the error stack, is in Errorcodes[0].
There's no way to get at the symbolic name of the custom exception. The errorcodes are passed across as integers. For the system-defined exceptions, IBO has constants in IB_Header.pas that reflect the symbolic names exposed in iberror.h. For custom exceptions, i.e., the ones created in the database using CREATE EXCEPTION, the ERRCODE constant will be the RDB$EXCEPTIONS.RDB$.RDB$EXCEPTION_NUMBER that you can see if you query the system tables. If the WHEN ... handler in your trigger or SP raises your custom exception then this is the one that will be in Errorcodes[0].
Of course, IBO has no constants defined to represent your custom errorcodes, so a handy way to keep on top of these in your app would be to name constants for your RDB$EXCEPTION_NUMBER numbers, with symbols "matching" the identifiers in the database.
For example, suppose you had this definition in your DB:
CREATE EXCEPTION ROLE_EXISTS 'This person already has this role';
Here, in a BeforeInsert trigger, we want to intercept a specific uniqueness violation on 2 keys (NEW.person_id and NEW.role_id) during execution of a Before Insert trigger and pass a pinpointed exception message back to the client. (In Fb 2 you can override the declared message and do some wonderful things with custom exception message text!) Suppose that, in RDB$EXCEPTIONS, the RDB$EXCEPTION_NUMBER for this exception is 3...in your app, scoped inside in a custom error handler unit or perhaps in your datamodule, you might define a constant like this:
const
...
ROLE_EXISTS = 3;
...
Then your error handler can test Errorcodes[0] in the EIB_ISCError structure for ROLE_EXISTS. You might want to make it even more self-documenting by having each of the specific exceptions you want to handle with a client-side response, by created inherited custom EIB_ISCError classes for each one.
Not sure whether any of this addresses the question you intended to ask, though. ;-) If not, try to give more detail about what you want to do...
Helen