Troubleshooting‎ > ‎

Debugging: Read the Stack Trace

posted Mar 12, 2013, 6:41 AM by Eric Patrick   [ updated Dec 9, 2013, 12:52 PM ]

Debugging Quandis Business Objects

Troubleshooting a QBO installation requires knowledge of five key debugging tools:
  • browser: 'Developer Tools'
  • network: Fiddler
  • server: Visual Studio
  • database: SQL Server Profiler
  • log files: Notepad

Debugging the Browser

QBO makes use of over 40,000 lines of javascript code (prior to minification), and about 10,000 lines of css code.  The good news is that only about 1/3 of all that code is 'QBO' code; the remainder is off-the-shelf stuff that rarely contributes to problems, but you still need to be able to read through it.

You are welcome to use any browser platform to debug. If you feel you wish to debug in IE, please spend 15 minutes debugging in IE 9 or earlier using their debugging tool, then spend 3 minutes debugging in Chrome, and you will reach the same conclusion that Microsoft's internal development teams reached: don't waste your time in IE.  Firebug is a perfectly acceptable alternative to webkit's debugger.

Some tips from the Quandis team with respect to the webkit debugger:
  • webkit = the baseline open-source code of both Safari and Chrome
  • Find the Console, and play with it. You can experiement with what you want to make QBO 3 do before publishing js changes!
  • When the Console shows a js error, it include a line number on the right. Clicking that line number takes you to exactly the line of code that raised the error
  • Find the Sources tab: it allows you to access included js and css files
  • From the Sources tab, you can highlight any code, right click, and choose Evaluate in Console
  • Put your js in external files whenever possible; it makes troubleshooting substantially easier
  • Use qbo3.reload() from the console followed by a page refresh to force a refresh your js and css include files after you publish changes

Debugging the Network

QBO 3 makes extensive use of AJAX to communicate with the server. Monitoring XmlHttp requests that are transmitted over the wire is essential to effective debugging. Download Fiddler, and review the tutorials if you're not familiar with it. Some tips from the Quandis team:
  • Enable HTTPS debugging from Tools > Fiddler Options > HTTPS tab
  • Find the Inspectors tab, and peruse the various options available: Raw, WebForms, JSON, and XML inspectors are really, really useful
  • Composer will allow you to fake any submission to the server (including XML posts) (this is a great hacking tool - design your security assuming users will try this out!)
  • Statistics will allow you to measure transmission times and troubleshoot multiple simultaneous requests
Fiddler's Composer window allows you to simulate HTTP GETs and POSTs to a website. To effectively use this with QBO, do the following:
  • Login to a QBO site
  • Start Fiddler
  • Navigate to QBO any page
    • from the Inspectors > Raw tab, copy the Cookie: line from the raw request; this contains your QBO Security cookie
  • Click on Fiddler's Composer window
    • enter the URL to submit to
    • copy the Cookie: line from your request above to the Request Headers section
      • you only need the qbo.Security and ASP.NET_SessionId cookies
    • paste your payload into the Request Body section
    • click the Execute button
    • note a new session appears in the left pane
You can review a more robust tutorial on Fiddler's site.

Debugging the Server

All QBO developers should have a local QBO installation running under IIS on their development machine. It's fine to have this site using a connection string to a dev or uat database, but you need to have the server-side (C#) code running locally to effectively debug. If you encounter a server-side error, you need to know where to start debugging. Determine this from the stack trace found in the server-side error logs.

In the stack trace below, note the following:
  • Timestamp says 11:51:28 PM: this is GMT. 7 lines below that, you see 18:51:28: this is local time (EST in this case).
  • Scan for all of the 'Message' lines: this is the summary of errors trapped. In the stack trace below, we have:
    • General Exception (not so useful)
    • Error attempting to read the path '/Templates/Mortgage/CopyTest/CopyTest.Edit.xslt' in file object repository 'Template'. (excellent clue!)
    • Could not find a part of the path 'C:\inetpub\\Templates\Mortgage\CopyTest\CopyTest.Edit.xslt'. (excellent clue!)
  • If you cannot determine the cause of the error from Message lines, scan again for a line of code that sounds like a culprit
    • the inner-most exception will contain the line of code that actually raised the error; if it's from System.*, it's core Microsoft code
    • consider reading from the bottom up in a stack trace: in this case, the very last line of the inner exception is the crux of the issue (LocalFile.Read method)

Timestamp: 3/4/2013 11:51:28 PM

Activity: 00000000-0000-0000-0000-000000000000

Message: HandlingInstanceID: ea85ac7a-9feb-4197-87ee-49549498e9b4
An exception of type 'qbo.Exception.GeneralException' occurred and was caught.
03/04/2013 18:51:28
Type : qbo.Exception.GeneralException, qbo.Exception, Version=, Culture=neutral, PublicKeyToken=null
Message : General Exception
Source : 
Help link : 
Manager : Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.ExceptionManagerImpl
Data : System.Collections.ListDictionaryInternal
TargetSite : 
HResult : -2146233088
ThrowException : True
Stack Trace : The stack trace is unavailable.
Additional Info:

MachineName : MINBAR
TimeStamp : 3/4/2013 11:51:28 PM
FullName : Microsoft.Practices.EnterpriseLibrary.ExceptionHandling, Version=5.0.414.0, Culture=neutral, PublicKeyToken=null
AppDomainName : /LM/W3SVC/1/ROOT-1-130069145369323941
ThreadIdentity :
WindowsIdentity : IIS APPPOOL\DefaultAppPool
Inner Exception
Type : qbo.Exception.GeneralException, qbo.Exception, Version=, Culture=neutral, PublicKeyToken=null
Message : Error attempting to read the path '/Templates/Mortgage/CopyTest/CopyTest.Edit.xslt' in file object repository 'Template'.
Source : qbo.Attachment
Help link : 
Manager : Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.ExceptionManagerImpl
Data : System.Collections.ListDictionaryInternal
TargetSite : qbo.Attachment.AttachmentInfo Read(System.IO.Stream, System.String)
HResult : -2146233088
ThrowException : True
Stack Trace :    at qbo.Attachment.FileObjects.LocalFile.Read(Stream stream, String relativePath) in C:\Source\Trunk\qbo.3\qbo.Core\Application Tier\qbo.Attachment\FileObjects\LocalFile.cs:line 60
  at qbo.Attachment.AttachmentObject.Read(Stream streamToWriteTo) in C:\Source\Trunk\qbo.3\qbo.Core\Application Tier\qbo.Attachment\Attachment.cs:line 435
  at qbo.Attachment.AttachmentObject.ReadMemory() in C:\Source\Trunk\qbo.3\qbo.Core\Application Tier\qbo.Attachment\Attachment.cs:line 446
  at qbo.Attachment.AttachmentObject.ReadXsl(XsltSettings settings) in C:\Source\Trunk\qbo.3\qbo.Core\Application Tier\qbo.Attachment\Attachment.cs:line 511
  at qbo.Attachment.AttachmentObject.ReadXsl() in C:\Source\Trunk\qbo.3\qbo.Core\Application Tier\qbo.Attachment\Attachment.cs:line 500
  at qbo.Decision.ImportFormTemplateObject.get_EditTransform() in C:\Source\Trunk\qbo.3\qbo.Core\Application Tier\qbo.Decision\ImportFormTemplate.cs:line 248
  at qbo.DecisionWeb.ImportForm.RenderEdit(HttpContext context) in C:\Source\Trunk\qbo.3\qbo.Core\Web Tier\qbo.DecisionWeb\Decision\ImportForm.ashx.cs:line 152
  at qbo.DecisionWeb.ImportForm.ProcessRequest(HttpContext context) in C:\Source\Trunk\qbo.3\qbo.Core\Web Tier\qbo.DecisionWeb\Decision\ImportForm.ashx.cs:line 60

Inner Exception
Type : System.IO.DirectoryNotFoundException, mscorlib, Version=, Culture=neutral, PublicKeyToken=b77a5c561934e089
Message : Could not find a part of the path 'C:\inetpub\\Templates\Mortgage\CopyTest\CopyTest.Edit.xslt'.
Source : mscorlib
Help link : 
Data : System.Collections.ListDictionaryInternal
TargetSite : Void WinIOError(Int32, System.String)
HResult : -2147024893
Stack Trace :    at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
  at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
  at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access)
  at qbo.Attachment.FileObjects.LocalFile.Read(Stream stream, String relativePath) in C:\Source\Trunk\qbo.3\qbo.Core\Application Tier\qbo.Attachment\FileObjects\LocalFile.cs:line 39

Category: General

Priority: 0

EventId: 100

Severity: Error

Title:Enterprise Library Exception Handling

Machine: MINBAR

App Domain: /LM/W3SVC/1/ROOT-1-130069145369323941

ProcessId: 5584

Process Name: c:\windows\system32\inetsrv\w3wp.exe

Thread Name: 

Win32 ThreadId:7172

Extended Properties: 

Debugging the Database

Debugging the database should be used when other technique fail. Profiling a server, particularly a PROD server, is 'expensive' in that the act of profiling can degrade the performance of the db all by itself. Thus, you should coordinate with a DBA or QBO architect if you need to profile a database for your debugging efforts. When profiling QBO3, consider:
  • Use the 'TSQL' template
  • Under 'Events Selection':
    • enable RPC:Starting and SQL:BatchStarting (and/or their Ending counterparts)
    • disable all Security Audit and Sessions checkboxes
    • check on Show all columns
    • click on Column Filters and add a filter on the DatabaseName for the database you are troubleshooting
  • Pause the trace until you are ready to replicate the issue
  • Run the trace, replicate the issue, and re-pause the trace

Log Files

All QBO errors are logged to the web server. QBO 3 logging uses the Microsoft Enterprise Library Logging sinks, including a rolling log file that is renamed each day. Some tips include:
  • If both IIS and the Queue Processor are running, they may conflict in their attempts to write to the rolling.log file. If so, you may see a {Guid}rolling.log file on the web server. Look at it's contents if you don't see what you expect in the standard rolling.log.