Skip to content

TWebSentry

TWebSentry

Sentry.io is a cloud-based error monitoring service that can log errors from your Web App even when it is being used by the customers.

Each error is logged as an issue and you can see the Stack Trace for each issue that can help diagnose the problem.

Once the issues are logged, the Sentry dashboard has convenient features to manaage these issues, for example, to assign them to other users who can see their issues and so on.

TMS Web Core provides a component “TWebSentry” that integrates Sentry.io with your web core application. It encapsulates all the logic of sending errors to Sentry so that they are logged as Issues. Also, the issues logged by TWebSentry in Sentry contain a Stack Trace that conveniently shows the Delphi Pascal code.

Steps to set up

Sign up with Sentry.io

You can get started for Free.

Please go to https://sentry.io/auth/login/ and sign in with Google. It will ask you to sign up as a New Organization. Select an organization name and proceed to set up the account.

Perform these steps in the Dashboard

Create a project. Select JavaScript as the platform. Enter a project name. On adding the project, it will display a screen of instructions. Please ignore them as the Sentry web core component will be doing all that for you. Scroll to the bottom and you will see a button “Take me to the Issue Stream.”

Click the button and it will show the Issues screen saying “Waiting for verification event.”

Note that later you will be reaching the same Issues screen often from the “Issues” menu on the left. The event will complete when you follow the steps given below to set up your Delphi Web Core App so that its errors end up as Issues on this screen.

Open DemoSentry project in Delphi

For the purpose of Demonstrating TWebSenty, there is a DemoSentry project in TMS Web Core. In the following discussion, we give steps to use this Demo to see various features.

Copy required parameters from the Dashboard to Paste in Sentry Demo

The dashboard screens below use an organization name as “tms-software” and the project name as “demo-sentry”. But you can select any other names and it will still work with DemoSenty as long as the following steps are completed properly.

First bring up Project Settings To do that, click on the drop down next to project name at the top.

Click on the Gear icon next to the project as shown above. Select “Client Keys (DSN)” on the Settings menu under SDK SETUP. Copy the value of the DSN box by using hte button next to it.

Paste the DSN in the DemoSentry project as given below

Open the source code of the unit USentry.pas. Paste the DSN value for the DSN property of the component in WebFormCreate. Now Build the project and Run it. You will see the following screen in the browser.

The purpose of this Demo is to create a variety of error types to see how they appear in Sentry Dashboard as issues. You can always look at the Form code to see the actual sample code.

Let’s raise a Delphi Exception, catch it and send to Sentry

We will force a Delphi error in code, catch it in an Exception block and then send it to Sentry by a CaptureException call. To do that, click on the button “Catch Delphi Error and Send to Sentry” that executes the following code.

As you can see, the exception is sent by calling method CaptureException of WebSentry1 component. The second parameter is an optional remark that we can fill up and send.

Now switch to the Sentry dashboard in the browser

We want to see if an Issue is recorded for the Delphi exception. If you see the Issues screen that was waiting for an event, you should see an Issue now.

The second line above shows the error message that we raised the Delphi Exception with in earlier code.

This is great because you will be able to see the errors from your TMS Web Core App in Sentry as issues

Further, you will be able to see the errors no matter where the customer is using the App.

What is even more useful is that you will be able to see the Stack Trace at the time of error

Click on the above Issue to see the details. Scroll down a little and you should see the Stack Trace.

But you will notice that this Stack Trace shows the JS code. That’s not so useful. Why don’t we see the Pascal code?

The reason is that the demo is running on localhost which Sentry can not access. If you copy the files of this demo to a web site and then follow the same steps as above to produce an issue, you will see the Delphi code with Pascal Stack Trace.

Let’s get the proper Pascal Stack Trace by running this demo from a web location

Go to the htdocs directory on your computer where the Web App is created by the build. From there, copy the output files to a web host. Now run the same Demo from there and produce the same issue. If you see the stack trace for that issue, you should see the proper Pascal stack trace as in the following screenshot.

See how the correct source line that raises Delphi exception is shown from the Pascal unit USentry.pas.

More on the Source Map file

If you see the htdocs folder for DemoSentry project where a build operation creates the output files for the Web App, you will 2 JS files. DemoSentry.js DemoSentry.js.map

The map file is the source map file that is needed to show the proper stack trace in Pascal. When you uploaded the Web App to a web host above and ran the Web App from there, Sentry could access the map file and could log the proper Pascal stack trace with the issue. Note that currently the map file is only created when the project is built in Debug configuration.

An option to create the map file should be there for Release configuration too so that Web Apps in production also get this feature to send Pascal stack trace. Security Problem with the hosted Map file Putting the source map file on the web host is a security risk because then it can be accessed publicly and seen with all the code for the App!

The solution is to upload the source map file to Sentry and remove it from the web host so that it is not publicly available and is only available to Sentry when logging its issues. This is an advanced operation and requires you to install a command line tool called Sentry-cli on your system. Please refer to the Sentry documentation to see how to download and install Sentry-cli.

Using Sentry-cli to upload MAP file to Sentry

Let’s assume that you hosted the DemoSentry files from C:to the following web location: https://mytest.com/DemoSentry

If so, the command line to upload the map file to Sentry is: sentry-cli releases --org tms-software --project demo-sentry files "DemoSentry@1.0" upload-sourcemaps C:\htdocs\DemoSentry --url-prefix https://mytest.com/DemoSentry --rewrite

Where tms-software is the organization from the dashboard, demo-sentry is the project name from the dashboard and “DemoSentry@1.0” is the Release from the Delphi source file. Release is explained in the next section. The above command uploads both the JS and JS Map file to Sentry. Then you can remove only the Map file from the hosted web app and the stack trace will still appear properly with the issues logged after that.

What is a release

You will notice a property Release set up for the WebSentry1 component in the Delphi USentry unit source along with the DSN. In Sentry, the issues are always under a release. This is quite logical because once you do bug fixes for errors, you are creating another release of your app. In that case, you should change the Release value in the Delphisource file. That way the errors (issues) related to a different releases are kept separate. For the same reason, the source maps are also associated with a Release. So when you have another Release, you will need to upload your new Source Map files under the new release.

Continuing with the rest of the Demo

1) Catch Delphi Error and Send to Sentry
We have already seen this case of sending a “caught” Delphi error to Sentry and inspecting the logged issue along with the stack trace in Sentry dashbaord. There are 3 other error conditions demonstrated in the Sentry Demo.

2) Catch JS Error and Sendto Sentry
To see this in action, click on the button “Catch HS Error and Send to Sentry.”

You can try this, look at the code sample and see how the issue and stack trace appears in Sentry.

As you can see, the call stack is correct, pointing to the proper line in the source that throws the error.

How to log an additional remark along with the Exception

If you see the code that calls CaptureException in the unit, you will see a second parameter that can send an optional Remark string to be logged in the issue.

To see this in action, enter some text in the Remark text box before you click on the Catch Delphi Error button. Then if you see the details of the newly logged issue in the Sentry Dashboard, you will see the Remark in the Additional Data section further down the page as shown in the following screenshot.

What happens if Unexpected Errors occur in the Web App?

The cases that we saw earlier are anticipated errors that we catch and send to Sentry by calling CaptureException. What happens when unexpected errors occur either in your Web App or in Web Core? They are automatically sent to Sentry to be logged as issues. This feature is demonstrated with the second group of buttons in the Demo under “Simulate unexpected (Uncaught) errors.”

3) Raise Delphi Exception Uncaught

Just click on the button “Raise Delphi Exception Uncaught.” The code just raises a Delphi exception to simulate this condition. It doesn’t catch it or call any Sentry method. Still, the error is reported to Sentry properly. See the corresponding issue and the call stack in Sentry dashboard.

As you can see, the call stack is correct, pointing to the proper line that raised the Delphi Exception in the USentry unit. Isn’t this wonderful? This means you don’t even need to modify your Web App. Just use the WebSentry component as described above and you get this feature out-of-the-box. Any Delphi exceptions occurring in your code or in Web Core on the Customer locations will be reported as issues in the Sentry dashboard.

4) Throw JS Error Uncaught

Similarly if you click on the second button, it throws a JS Error that is automatically sent to Sentry and logged as an issue with the following stack trace.

5) How to log a message to Sentry?

Sometimes, even without errors, you may want to log an informational message in Sentry log.

This can be done by calling CaptureMessage function of the WebSentry component. In the Demo, click on the button “Send Log Message to Sentry” to do that. It will appear in Sentry issues like the following screenshot.

Even the stack trace will be there if you look into the issue details.

More features in Sentry

These are not used in the Demo but methods exist in TWebSentry component to use these features. Set User Sentry logs issues from all the customers using your Web App. In that case, how can you disinguish an issue coming from a particular user? By default, Sentry logs the ip address as user at the top of the issue. But you can do better and set a user yourself by calling SetUser method of TWebSentry as soon as you can identify the user, for example, after Login. For example, WebSentry1.setUser('john@example.com'); It can be even a user name or id and is entirely upto your app on how you identify the user. Once that is done, all the issues logged will be under this user. In Sentry dashboard when you click on an issue, at the top right, you will see how many users are facing this issue. Click on it and you will see the list as shown below.

Sentry supports a concept called Breadcrumbs, which is a trail of events which happened prior to an issue. For any of the exceptions described above, a breadcrumb appears. When you log a message to console, it also appears as breadcrumb. In addition, you can call TWebSentry’s method AddBreadcrumb to add a breadcrumb with a category and a message. Here is a a sample screenshot of breadcrumbs.

The first breadcrumb was added by calling AddBreadcrumb with category “auth” and a message to show that a user logged in. Even the user’s identity could have been logged here. Similarly, the second breadcrumb has a category “data” and a message. The third breadcrumb is automatic from the exception that occurred. So the breadcrumbs give us a quick summary that user logged in, data was obtained and then the exception occurred.

Tags

Sentry automatically sets many tags for more details on an issue, for example, browser, os, release, etc. Moreover, the issues can be searched by tags quickly. For example, you can quickly search for issues occurring on OS Windows 7. You can set custom tags too by calling SetTag method of TWebSentry. Once you set a tag, it appears on all issues logged after that. Here is an example,

WebSentry1.SetTag('ReleaseNote', 'Grid problem fixed.');
Here is how the tag appears in the dashboard.

In this case, the tag appears first in the tag cloud.

Properties for TWebSentry

Property Description
Enabled When True sends information to Sentry. Set it to False to disable sending it.
DSN Required. Obtained from Project Settings in Sentry dashboard
Release Set it to a String that identifies the Release and groups issues under that release. Can be any String, recommended name@version format.

Methods for TWebSentry

Property Description
Init If you set DSN and Release property values at design time in Object Inspector then you don’t need to call Init explicitly. It’s automatically called on loading the form. But if you set DSN and Release property values in code, you must call Init after setting them.
CaptureException procedure CaptureException(anObj: TJSObject; remark: string='');
The component automatically sends Exceptions and Errors to Sentry as long as they are Uncaught. But if you are catching certain Delphi Exceptions or JS Errors in your code, they won’t be sent to Sentry for logging unless you explicitly send them by calling CaptureException. Just pass the Delphi Exception object or a JS Error object that you caught as the first parameter to above function. Note that these objects already contain an error message. But if you want to send some additional information, you can send it as a string in the second parameter to CaptureException.
CaptureMessage procedure CaptureMessage(aMsg: string);
To send and log an informational message in Sentry log, call CaptureMessage with a string.
SetUser To better identify issues, set a user soon after you can identify if in the web app, for example, after login. Pass anything for aName that you can identify in the log. For example, it can even be an email address or an id.
procedure SetUser(aName: string);
AddBreadCrumb Adds a breadcrumb to be listed in Sentry log.
procedure AddBreadcrumb(aCategory: string; aMessage: string);
Choice of category string is arbitrary. Use anything that makes sense in the logs.
SetTag Sets a custom tag with a key, value paid that is listed in the issue Tags. The issue also becomes searchable by the tag.
procedure setTag(aKey: string; aValue: string);