Anatomy of an OutSystems error stack

Anatomy of an OutSystems error stack

  
Introduction
 
Everyone working with the Agile Platform is aware of the advanced logging capabilities, among which the automated error capturing and handling. These logs are automatically written to the database, and visible in Service Center.
 
The information in the error stack is very detailed and should give you all the elements you need to analyze the problem - be it in your application logic or somewhere else. However, some may be scared when first looking at an error stack, and thus not taking full advantage of this information.
 
With this post I will introduce some of the common elements in the Agile Platform error stack, and hopefully help you with troubleshooting your errors. I will start off with a basic error stack and then will be adding further error stacks which add relevant information to what was already said earlier.
 
As with all forums posts your contribution is important - so whenever you detect a new pattern, feel free to contribute with your explanation, or simply post the question if you don't know the answer.
 
 
A basic error stack
The best way to explain an error stack is to look at one, and start tearing it into pieces. Below you can find a sample error stack (taken from another post, http://www.outsystems.com/NetworkForums/ViewTopic.aspx?Topic=Internal-Error-instead-of-showing-the-Default-Image):
 
Service Center Version: 6.0.0.6 (build 27043: tags/v6_0_0_6 @ 2011-06-21 22:19:25)
 
Module_Name: 
 
Message :"outsystems"."DBO"."OSUSR_8JS_OGRENCIPICTURE" with key 31 was not found
 
Stack:    at ssGBA.ExtendedActions.GetOgrenciPicture(HeContext heContext, Int32 inParamId, RCOgrenciPictureRecord& outParamRecord)
   at ssGBA.Functions.ssGetOgrenciPicture(HeContext heContext, Int32 inParamId)
   at ssGBA.Flows.FlowMainFlow.ScrnSinifOgrenci_List.img5_getFilename()
   at ASP.sinifogrenci_list_aspx.__DataBinding__control99(Object sender, EventArgs e)
   at System.Web.UI.Control.OnDataBinding(EventArgs e)
   at System.Web.UI.Control.DataBind(Boolean raiseOnDataBinding)
   at System.Web.UI.Control.DataBind()
   at OutSystems.HubEdition.WebWidgets.DynamicImage.DataBind()
   at System.Web.UI.Control.DataBindChildren()
   at System.Web.UI.Control.DataBind(Boolean raiseOnDataBinding)
   at System.Web.UI.Control.DataBind()
   at System.Web.UI.Control.DataBindChildren()
   at System.Web.UI.Control.DataBind(Boolean raiseOnDataBinding)
   at System.Web.UI.Control.DataBind()
   at System.Web.UI.WebControls.DataGrid.CreateItem(Int32 itemIndex, Int32 dataSourceIndex, ListIt....Control.DataBind()
   at System.Web.UI.Control.DataBindChildren()
   at System.Web.UI.Control.DataBind(Boolean raiseOnDataBinding)
   at System.Web.UI.Control.DataBind()
   at OutSystems.HubEdition.WebWidgets.OSPage.DataBind()
   at ssGBA.Flows.FlowMainFlow.ScrnSinifOgrenci_List.DataBind()
   at ssGBA.Flows.FlowMainFlow.ScrnSinifOgrenci_List.Page_Load(Object sender, EventArgs e)
   at System.Web.UI.Control.OnLoad(EventArgs e)
   at System.Web.UI.Control.LoadRecursive()
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
-Env-
eSpaceVer: 138 (Id=192, PubId=203, CompiledWith=6.0.0.6)
RequestUrl: http://212.175.206.151/GBA/SinifOgrenci_List.aspx
AppDomain: /LM/W3SVC/1/Root/GBA-4-129561187666875000
FilePath: C:\...\PS\running\GBA.01985253024\SinifOgrenci_List.aspx
Locale: en-US
DateFormat: dd/MM/yyyy
PID: 2528 ('w3wp', Started='7/26/2011 1:17:47 AM', Priv=191Mb, Virt=692Mb)
TID: 7
.NET: 2.0.50727.3623
 
eSpace Name: GBA
 
Tenant Name: GBA
 
InstallerId: 233FF278-4DE0-234B-B38E-8F08ABDBC382
License Edition: Community Edition
Windows Version: Microsoft Windows NT 5.2.3790 Service Pack 2
 
So what does this error stack tell us? Actually, a lot!
 
Service Center Version: 6.0.0.6 (build 27043: tags/v6_0_0_6 @ 2011-06-21 22:19:25)
This indicates us the version and revision of Service Center (and thus, of Platform Server). You can use this, among others, to check the change log (if you suspect that the error is not with your app but with the Agile Platform) and to provide to Support.
 
Message :"outsystems"."DBO"."OSUSR_8JS_OGRENCIPICTURE" with key 31 was not found
The actual error message. Plenty of times you can get to know exactly what is the problem just by knowing where it happened and the actual error message! Other times you will need to run through the rest of the error.
If the error comes from an OutSystems built-in API, you may get Module information. This is most of the times self-explanatory - I may revisit this later.
 
In the end of the error stack, you can also know that the error occurred in eSpace Name: GBA and Tenant Name: GBA. In multi-tenant eSpaces, Tenant Name will typically be different from eSpace Name - in regular eSpaces, this will always be the same. So if you don't know what multi-tenant is, and see an eSpace Name different than Tenant Name, beware.
 
The -Env- part gives us a lot of technical details about the runtime context in which the error occurred:
 
  • eSpaceVer: 138 (Id=192, PubId=203, CompiledWith=6.0.0.6)
    This indicates that the error occurred with eSpace version 138 (the number you see listed when you see the version list in Service Center) and that it was compiled with Platform Server 6.0.0.6. This number will typically be the same as Service Center Version, but if it is not, beware: you may be expecting different behaviors since your latest patch to the Agile Platform (e.g. to fix a specific bug) but things remained the same. Note that most of the Agile Platform fixes will require you to both patch the Agile Platform and republish all the components to take advantage of the fix.
     
  • RequestUrl: http://212.175.206.151/GBA/SinifOgrenci_List.aspx
    This indicates the URL that the user requested. You can see things like the way the user accessed (in this case it was by IP address; it could have used a specific name like www.mydomain.com) and more importantly, the web page where the error happened (SinifOgrenci_List). You could also see here a web service or, if you see something ending in _TimerHandler.asmx, then the error was with a Timer.
     
  • AppDomain: /LM/W3SVC/1/Root/GBA-4-129561187666875000
    FilePath: C:\...\PS\running\GBA.01985253024\SinifOgrenci_List.aspx
    The above two lines indicate the IIS AppDomain (/LM/W3SVC/1/Root/GBA-4-129561187666875000 - information about AppDomains here) and, more importantly, the location of the file.
    Note that this error trims out unimportant information - it will just give you the path below the Platform Server installation folder, and the drive. So in this case, Platform Server is installed in a folder in C:, the folder itself is named "Platform Server" (and was shortned to PS), and the file is inside running\GBA.01985253024.
     
  • Locale: en-US
    DateFormat: dd/MM/yyyy
    This indicates the Agile Platform Locale setting (http://www.outsystems.com/help/servicestudio/6.0/Multilingual_eSpaces/Adding_Other_Languages.htm) and the date format. Can be handy when troubleshooting specific settings (e.g. if you have an error that only happens on a specific locale in your multilingual application, maybe you are assuming a specific spelling for some string?)
     
  • PID: 2528 ('w3wp', Started='7/26/2011 1:17:47 AM', Priv=191Mb, Virt=692Mb)
    TID: 7
    .NET: 2.0.50727.3623
    This last part gives us a lot of internal details about the way the IIS request was being executed - it indicates the process ID (PID) of the worker process running your request, some memory indicates (Private bytes and Virtual bytes), the thread that was running your request, and the actual version of .NET. This may come in handy when troubleshooting advanced problems (e.g. OutOfMemory errors and worker process crashes).
Finally, we come to what we wanted: the error stack. To it looks like this:
 
Stack:    at ssGBA.ExtendedActions.GetOgrenciPicture(HeContext heContext, Int32 inParamId, RCOgrenciPictureRecord& outParamRecord)
   at ssGBA.Functions.ssGetOgrenciPicture(HeContext heContext, Int32 inParamId)
   at ssGBA.Flows.FlowMainFlow.ScrnSinifOgrenci_List.img5_getFilename()
   at ASP.sinifogrenci_list_aspx.__DataBinding__control99(Object sender, EventArgs e)
   at System.Web.UI.Control.OnDataBinding(EventArgs e)
   at System.Web.UI.Control.DataBind(Boolean raiseOnDataBinding)
   at System.Web.UI.Control.DataBind()
   at OutSystems.HubEdition.WebWidgets.DynamicImage.DataBind()
   at System.Web.UI.Control.DataBindChildren()
   at System.Web.UI.Control.DataBind(Boolean raiseOnDataBinding)
   at System.Web.UI.Control.DataBind()
   at System.Web.UI.Control.DataBindChildren()
   at System.Web.UI.Control.DataBind(Boolean raiseOnDataBinding)
   at System.Web.UI.Control.DataBind()
   at System.Web.UI.WebControls.DataGrid.CreateItem(Int32 itemIndex, Int32 dataSourceIndex, ListIt....Control.DataBind()
   at System.Web.UI.Control.DataBindChildren()
   at System.Web.UI.Control.DataBind(Boolean raiseOnDataBinding)
   at System.Web.UI.Control.DataBind()
   at OutSystems.HubEdition.WebWidgets.OSPage.DataBind()
   at ssGBA.Flows.FlowMainFlow.ScrnSinifOgrenci_List.DataBind()
   at ssGBA.Flows.FlowMainFlow.ScrnSinifOgrenci_List.Page_Load(Object sender, EventArgs e)
   at System.Web.UI.Control.OnLoad(EventArgs e)
   at System.Web.UI.Control.LoadRecursive()
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
 
In error stacks, you can separate things into groups:
  • Lines that start with OutSystems are part of the Agile Platform code - so it is calls to internal OutSystems API;
  • Lines starting with ss<something> refer to an eSpace named <something>
  • Most of the remaining lines refer to .NET or third-party primitives.
 
In later posts I will indicate other lines that refer to other OutSystems code.
 
So in this case, and looking from the bottom to the top, you can see:
 
Some .NET primitives related to the actual triggering of the request;
   at System.Web.UI.Control.OnLoad(EventArgs e)
   at System.Web.UI.Control.LoadRecursive()
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
 
at ssGBA.Flows.FlowMainFlow.ScrnSinifOgrenci_List.Page_Load(Object sender, EventArgs e)
Then code inside the eSpace. In this case you have eSpace GBA, Web Flow MainFlow, screen SinifOgrenci_List. This particular line indicates that Page_Load is running - i.e. the screen is being rendered. The line above this one indicates DataBind(), meaning associating data to the widgets in your screen.
 
All the lines between
   at System.Web.UI.Control.OnDataBinding(EventArgs e)
   (...)
   at OutSystems.HubEdition.WebWidgets.OSPage.DataBind()
are related to the internal process of recursively binding all widgets, and this is not interesting (at least for now). But at the top, we have again our eSpace:
 
   at ssGBA.ExtendedActions.GetOgrenciPicture(HeContext heContext, Int32 inParamId, RCOgrenciPictureRecord& outParamRecord)
   at ssGBA.Functions.ssGetOgrenciPicture(HeContext heContext, Int32 inParamId)
   at ssGBA.Flows.FlowMainFlow.ScrnSinifOgrenci_List.img5_getFilename()
 
This indicates that, again in our SinifOgrenci_List screen, this happened rendering an image, trying to get a file for an image widget, and then, calling a built-in action (ExtendedActions) Get<Entity>. In our case entity is OgrenciPicture.
 
So in the end, and just by looking at the error message and top 3 lines in the error stack:
 
Message :"outsystems"."DBO"."OSUSR_8JS_OGRENCIPICTURE" with key 31 was not found
 
Stack:    at ssGBA.ExtendedActions.GetOgrenciPicture(HeContext heContext, Int32 inParamId, RCOgrenciPictureRecord& outParamRecord)
   at ssGBA.Functions.ssGetOgrenciPicture(HeContext heContext, Int32 inParamId)
   at ssGBA.Flows.FlowMainFlow.ScrnSinifOgrenci_List.img5_getFilename()
 
You can tell that the error is that GetOgrenciPicture is giving a database error ("outsystems"."DBO"."OSUSR_8JS_OGRENCIPICTURE" with key 31 was not found) - meaning your screen is trying to get an entity record with identifier 31, and not finding it. This error also exposes the physical table name in the database - so now you know that your entity OgrenciPicture is saved in the database under table "outsystems"."DBO"."OSUSR_8JS_OGRENCIPICTURE".
 
Stay tuned for more episodes.
Cheers,
Hi
 
In today's post I will cover basic examples of references. I will refer to the errors in these posts:
 
In the first post, we have this error message & stack
 
The remote server returned an error: (401) Unauthorized. 
at System.Net.HttpWebRequest.GetResponse() 
at OutSystems.NssRichMail.CssRichMail.MssHttpBinaryGet(String ssUrl, String& ssContentType, Byte[]& ssContent) 
at ssMGF.RssExtensionRichMail.MssHttpBinaryGet(HeContext heContext, String inParamUrl, String& outParamContentType, Byte[]& outParamContent) 
at ssMGF.Actions.UserActionEnviarEmail(HeContext heContext, String inParamTo, String inParamSubject, String inParamBody, String inParamURL) 
 
So for this error, the message is:
The remote server returned an error: (401) Unauthorized. 
 
And the error stack is
at OutSystems.NssRichMail.CssRichMail.MssHttpBinaryGet(String ssUrl, String& ssContentType, Byte[]& ssContent) 
at ssMGF.RssExtensionRichMail.MssHttpBinaryGet(HeContext heContext, String inParamUrl, String& outParamContentType, Byte[]& outParamContent) 
at ssMGF.Actions.UserActionEnviarEmail(HeContext heContext, String inParamTo, String inParamSubject, String inParamBody, String inParamURL) 
 
Again, reading from bottom to the top, we see that:
 
at ssMGF.Actions.UserActionEnviarEmail(HeContext heContext, String inParamTo, String inParamSubject, String inParamBody, String inParamURL
This error occurred in eSpace MGF, in a user action named EnviarEmail. This action receives parameters To, Subject, Body, URL.
 
at ssMGF.RssExtensionRichMail.MssHttpBinaryGet(HeContext heContext, String inParamUrl, String& outParamContentType, Byte[]& outParamContent
Now this is new. In this case, eSpace MGF is calling a reference to an extension (RssExtension) and the extension in this case is RichMail. And the action being called is HttpBinaryGet - with input parameter (inParam) Url and output parameters (outParam) ContentType and Content.
 
at OutSystems.NssRichMail.CssRichMail.MssHttpBinaryGet(String ssUrl, String& ssContentType, Byte[]& ssContent) 
And finally we have the code in the extension - Extension (Nss) Richmail, under class (Css) RichMail, and the action is HttpBinaryGet.

---
 
Here we learn that a call to a reference (in this case, an extension) is a two-step call:
  • First the calling eSpace calls a "reference proxy" to the producer;
    at ssMGF.RssExtensionRichMail.MssHttpBinaryGet(HeContext heContext, String inParamUrl, String& outParamContentType, Byte[]& outParamContent)
     
  • The "reference proxy" then calls the actual logic in the producer.
    at OutSystems.NssRichMail.CssRichMail.MssHttpBinaryGet(String ssUrl, String& ssContentType, Byte[]& ssContent) 
     
Things are always done like this in a producer/consumer scenario, because it is the proxy that handles problems like broken references. So if your reference to HTTPBinaryGet was broken, instead of a call to OutSystems.NssRichMail.CssRichMail.MssHttpBinaryGet, you would get the broken reference error.
 
 
In our second error, things are basically the same:
 
Message:
A sequência não permite a leitura.
 
Stack:
em System.IO.BinaryReader..ctor(Stream input, Encoding encoding)
em ExcelLibrary.CompoundDocumentFormat.CompoundDocument..ctor(Stream stream, FileHeader header)
em ExcelLibrary.CompoundDocumentFormat.CompoundDocument.Open(Stream stream)
em ExcelLibrary.CompoundDocumentFormat.CompoundDocument.Read(Stream stream)
em ExcelLibrary.SpreadSheet.Workbook.Load(Stream fileStream)
em ExcelLibrary.SpreadSheet.Workbook.Load(String file)
em OutSystems.NssexcelIntegration.CssexcelIntegration.MssWorkBook_Open(String ssFilePath, Object& ssWorkBook)
em ssApplication.RssExtensionexcelIntegration.MssWorkBook_Open2(HeContext heContext, String inParamFilePath, Object& outParamWorkBook)
 
So the message (which translates to "sequence cannot be read") is occurring in eSpace Application, calling extension excelIntegration (action WorkBook_Open2). Inside the extension, this is calling a 3rd party library ExcelLibrary (several methods called in sequence) which at some point calls System.IO.BinaryReader..ctor (the class constructor) which is yielding the error.
 
So in this case, you need to go look into the extension and find out what is wrong there - or what you are passing incorrectly to your action!

If you have any examples you may find interesting, please share them!
Cheers,

Acácio