Hello and welcome to debugging and monitoring, where we will discuss how to
troubleshoot your OutSystems application. Now, every time that you
write code, you know that code is subject to many errors, you can have logical
errors, whereby you actually write the code wrong and it doesn't do what you
intended to do. For example, you might have an if statement, that you want to
take the true path given a certain condition, but the code is actually
written to take the false path or you can have some logic that compute
something using a variable, which is not the one where you stored the values for
that computation.
Furthermore, there can be data errors, whereby the code itself is actually correct but
you use data that's inappropriate for the computation, for example, you might
divide by zero or you might insert a duplicate identifier in the database.
Furthermore, there are other assorted problems like performance, security and
connectivity issues, that also hinder the behavior of an application.
Troubleshooting is the process of going through, of finding, these errors and
addressing them and normally boils down to the process of debugging and
monitoring the life of an application. So what is debugging? Debugging
is the process of finding, with the intention of resolving, the defects
that are preventing the correct operation of a piece of software. In
practical terms, debugging normally involves stopping the code execution at a certain
point that you suspect is giving you problems and then stepping through the
individual statements of the code, all the time analyzing what the data context
is, what the variables hold. Once you lock into the statement or the set of
statements or the logic that's got problems, you can then finally fix your
code. Debugging in service studio, in the OutSystems platform, is very, very simple.
You can place breakpoints, on any element that generates code and you can
visually see that by a small marker, next to the node that's got the breakpoint. Now
by default, every time that you're running your code, the debugger isn't
enabled.
For the debugger to be enabled, you need to start the debugger so it is monitoring
the execution,
its looking out for the breakpoints that you've placed. At any time, at the
very bottom of your service studio, you have the debugger panel and over there
you can see what breakpoints you have in your current module and you can navigate
to them. On the right-hand side of the debugger panel, you have several buttons
that allow you to carry out to several debugger related actions, things like
stepping into, stepping out and breaking on errors. Now, when the code is stopped, you can
look at the value of the variables and you have several sub-tabs in the
debugger area. In the in-use tab, you can see all of the statements, all of the
variables that are involved in the current statement and actually the
outputs of the previous statement. In the locals you can see all of the variables
and all of the outputs that are local to the current context. Next, in the widgets
tab, you can see all of the values of the runtime properties of every widget on
your screen. On the session and site tabs, you can see the values for a few global
kinds of variables, that will be covered in a later lesson.
Finally, on the watches, you get to pick which variables appear there, so the most
interesting ones that you're focusing all your debugging in, you can
right-click on them, in any of the other panels, and say "Add to Watches" and they
will always appear on watches. Now, when you're debugging a module in service
studio
by default it debugs, it stops the execution, on the current module that you're
debugging. Sometimes this might not be what you want, for example, if you want to
debug a producer, as it's running within the context of a consumer, you need to
specify that the entry module should be a different one, so that the debugger
latches onto the version of the current module, as it's running within the
context of the entry
module. There's actually another nuance to debugging an OutSystems application
by default you debug the application in what's called the "public area" of the
application and this is where the official location of the application is
in the server. So for example, if you have an application called MyApp, you
normally go to yourserver/MyApp, this is the public area of your module and
this is the default place where you debug. The OutSystems platform actually
allows you to debug on what is called a "personal area" as well, this is a side
copy, per user, that you can use to try out your changes with little impact on the
public area, on the main area of the application. Using the personal area then,
therefore, has this lower impact but furthermore, the act of selecting to run
and debug in the personal area is normally a much faster operation. It is
worth noting, however, that changes to the data model, if you make changes to the
data model, you will need first to republish into the public area, prior to
running and debugging in the personal area. This is obvious because the
database is a shared resource, so you cannot have a local copy of the database
for your personal area, just a local copy of the code in your personal area. Now, if
you have done any programming, in modern languages, you already know about
exceptions.
Whenever a code operation fails, an exception is thrown and the same thing
happens in an OutSystems application. When this happens the code execution, the
normal code execution, is interrupted and it's moved to an alternate flow, that is
the error handler. In any context, in any action, you can actually have several error
handlers, depending on the nature of the error that you want to catch, so you can
have database exceptions, security exceptions or even custom
exceptions that you explicitly throw. So when an exception is thrown, the
execution is moved to the handler that is most specific to the exception thrown.
If no adequate error handler exists in the current code, the runtime will try to
find a suitable handler, in wherever the context that called the current one: it will
bubble up the exception.
Let's look at the practical example, in this particular case, the debugger is stopped
before a DB operation, we want to update a movie and we press step over with
intent of carrying on.
However, there was a database exception. We actually have two exception handlers
one for database and one for all exceptions but since the exception was a database
exception, we will catch it with the most specific one.
So the code execution moves to the database exception handler. As you can
see at the bottom of the screen, when an exception occurs, the details of this
exception, can be obtained from the output of the exception handler node.
Let's look in detail, into a couple of properties of the exception handler node.
One of them is the abort transaction, it dictates if all the database changes, the
writes and the deletes that you might have done during this request should be
rolled back or not. The default is yes but if you set it to no, then the
previous changes that you made to the database will still be maintained and
committed at the end of the current request. The second property, is the log
error property, this states if this error should end up in the error log of the
platform. The default again is yes but if you set it to no, this will not be logged.
Let's talk now a little bit about monitoring. The OutSystems platform
provides a complete set of logs that record all sorts of occurrences that
happened at runtime. Now, logged events are not limited just to errors but also can
include normal situations, for which the diagnostics might be interesting
say, for example, the duration of screen calls or the duration of web service
calls.
Monitoring is the act of analyzing and correlating these logs to find out
either errors that have occurred or patterns, maybe performance patterns, that
might need a change in the code for optimal execution. If you go into the OutSystems
environment management console, also known as service center, you'll see
that many kinds of logs are available, you have the obvious errors, general
audits, screen accesses and the times that they take, integration and extension
calls, timer calls and many, many other things. It is possible, as you can see
over here, to filter for specific modules to filter for specific application
time windows, etc. and you can also export the report to excel. If you notice the
rightmost column, the detail, you'll be able to get details on the particular
event, by clicking on that. And you have a wealth of information here that for
example, in the case of errors, will help you greatly find out what might be the
problem and how to address it.
The two most important fields over here is the message and the stack. The message
is very handy because, for example, if it is a SQL error, you probably can look
for this string, in non OutSystems discussion boards, and the stack, if you
pay close attention to what's there, you'll be able to see what is the
calling stack, that led to the error and therefore find this in your module. And
this is it for debugging and monitoring. Hopefully this information will come in
handy, when you're having problems with your application.
Bye for now.