Showing posts with label error. Show all posts
Showing posts with label error. Show all posts

Wednesday, 18 February 2026

SQL Server - How to capture database errors

One very useful addition to a database I have found recently is to capture database errors in a try...catch block and storing the information in a table. Here is what I did:

Table to store the error information:

CREATE TABLE dbo.DBErrors (
  DBErrorID INT IDENTITY
 ,Raised DATETIME NULL CONSTRAINT DF_DBErrors_Raised DEFAULT (GETDATE())
 ,Number INT NULL
 ,Severity INT NULL
 ,StateNumber INT NULL
 ,StoredProcedure NVARCHAR(128) NULL
 ,Line INT NULL
 ,ErrorMessage NVARCHAR(4000) NULL
 ,CONSTRAINT PK_DBErrors PRIMARY KEY CLUSTERED (DBErrorID)
) ON [PRIMARY]

Then I wrote a stored procedure to write to the table:

CREATE PROCEDURE dbo.DBErrorInsert
AS
BEGIN
DECLARE @DBErrorsExist bit;
  SET NOCOUNT ON;
  
  SELECT TOP (1) @DBErrorsExist = TableExists FROM dbo.efn_TableExists('DBErrors');
IF (@DBErrorsExist = 1)
BEGIN
INSERT INTO DBErrors (Number, Severity, StateNumber, StoredProcedure, Line,   ErrorMessage) VALUES ( 
ERROR_NUMBER(),  
ERROR_SEVERITY(),  
ERROR_STATE(),  
ERROR_PROCEDURE(),  
ERROR_LINE(),  
ERROR_MESSAGE());
    RETURN -2;
END
  ELSE
  BEGIN
    RETURN -1;
  END;
END;

Then where I wanted to capture any errors i.e. in a stored procedure I did the following:

BEGIN TRY
  ... Stored proc code
END TRY
BEGIN CATCH
  EXEC dbo.DBErrorInsert;
END CATCH

When an error occurs in the try...catch block it writes the error information including the line the error was triggered to a record in the table.



Tuesday, 6 March 2018

Why is there no Delphi error provider?

Recently I've been looking at the best solution for displaying a data entry validation error, for example when a user needs to enter a description that is not a duplicate and they enter a duplicate the user is informed of the error. Many web sites will display an error below the text box highlighting an error, or displaying an error icon next to the text box. In C# (Visual Studio 2017) when developing a forms application there is a 'ErrorProvider' component that is easy to use and displays an icon on the right (exclamation mark by default) with a hint that can contain the error text.

What I am looking for is something similar in Delphi (I am currently using Berlin), and I am surprised there is no 'out of the box' standard component that ships with Delphi that can do this.

I have looked at using a TButtonedEdit control with a right button visible with an exclamation mark as the icon when there is an error, but this does not work well.

I imagine that how software informs a user of a data entry validation error is subjective and some developers will have different ideas, but I am interested in what other developers think and are there any decent 3rd party products that have a single error component.       

Thursday, 25 May 2017

Frame Inheritance - TabOrder: Property does not exist - Issue Fixed

I've been working on an application recently and it has a few frames (TFrame), I noticed that there were common properties and methods to all the frames, so I decided that they should derive from a base class. I created the base frame class and then in code derived the other frames from the base frame. It all seemed to work fine a build and ran OK, however after closing the project and then coming back to it a few days later, when I tried to open a frame I received an error stating the TabOrder property does not exist, I ignored it and received more property does not exist errors (I did not save any changes). The solution to this problem was simple, in the .dfm file at the top was:

object TestFrame: TTestFrame 

This needed to be changed to:

inherited TestFrame: TTestFrame

The ideal way to do this is at design time when designing the structure of the application, if there is an abstract or concrete frame class then this should be added to the repository so when a developer needs to create a new frame, they can simply inherit the frame from the one in the repository.

This is a very similar problem to inheriting datamodules, I've also had to do something similar. 

Tuesday, 21 June 2016

Delphi error XML document must have a top level element. line 0

I have a Delphi application written in XE that consumes a WCF service written in C#, I have been receiving the following error message with one of the methods

XML document must have a top level element. line 0

I managed to fix the issue by making the method in the WCF Service return a value (boolean) if successful. It is possible Delphi does not like WCF Service methods that are one way ([OperationContract(IsOneWay = true)]).

Thursday, 18 July 2013

How NOT to handle exceptions

Just been working with some code and saw this little gem.

try
  {Some code}
except
  showmessage('error');
end;

This is a good example of the developer being lazy and not being bothered to do something better. Can you imagine the user ringing up support and saying they are getting a 'error' message, it's not even with a capital 'E'. 

There are a couple of issues I have with this bit of code. Firstly I have a rule that showmessage() is used while developing and should be removed when a deployment build is done, if a message needs to be displayed it should be in an message dialog (MessageDlg). The reason for this is that a message dialog looks better with icons specify what the message is, I use GExperts to create the code. Also, when developing I can quickly search for 'showmessage' and can see what messages need to be removed, this means there are no embarrassing debug messages displayed to the user.

Secondly is the message just says error, which it not helpful to the user or the developer when it is reported. The developer could have done something better by giving a more useful message like 'An error has occurred while...', with what the operation is doing. The developer could have also included the exception message like the following.

try
  {Some code}
except 
   on e: exception do
     MessageDlg('An error has occured in...' + e.Message,                mtError, [mbOK], 0);
end;