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 Delphi
source 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 Send
to 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.
Breadcrumbs
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,
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); |