package com.smartgwt.client.docs;
/**
* <h3>Debugging</h3>
* <h4>Built-in Diagnostics</h4>
* <P>
* The Smart GWT Developer Console is a suite of development tools implemented in Smart GWT itself.
* The Console runs in its own browser window, parallel to your running application, so it is always
* available in every browser, and in every deployment environment.
* <P>
* The Developer Console can be opened by calling <code>isc.showConsole()</code> on any page in which
* Smart GWT has been loaded. You can create a bookmark in your browser to quickly show the Console on
* any Smart GWT application, without any changes to the application code:
* <P>
* 1. Create a new bookmark in your browser.<BR>
* 2. Enter url "javascript:isc.showConsole()".<BR>
* 3. Label the bookmark as "Show Console".<BR>
* 4. Consider adding this to the Bookmarks Toolbar. This allows one-click access to the Console
* from any Smart GWT application.
* <P>
* Note: For most browsers you can evaluate javascript directly from the browser URL bar by entering
* <code>javascript:<i>string to evaluate</i></code> directly in the URL bar, so setting up a bookmark
* is not strictly necessary. For Firefox 6 and above, this feature has been disallowed, but the bookmark
* approach will still work. Alternatively developers could use
* <a href='http://blog.mozilla.com/devtools/2011/08/15/introducing-scratchpad/'
* onclick="window.open('http://blog.mozilla.com/devtools/2011/08/15/introducing-scratchpad/');return false;">Firefox
* Scratchpad</a>
* to launch the console.
* <P>
* Basic information on the features of the Developer Console can be found in the QuickStart
* Guide. This topic focuses on use of the log system and related debugging facilities.
* <P>
* The Developer Console contains a "Results" pane that displays a list of diagnostic
* messages logged by the Smart GWT framework. The "Logging Preferences" menu lets you
* enable and disable Smart GWT's built-in diagnostics in several categories. Because
* important diagnostic messages may be logged at any time, you should have the Developer
* Console open whenever you are working with Smart GWT (and you should bookmark the
* "javascript:" expression above to make this easier).
* <P>
* Log messages are of the format:
* <P>
* <i>timestamp</i>:<i>priority</i>:<i>category</i>:<i>message</i>
* <P>
* For example, the following log message:
* <pre>
* 11:59:25:806:INFO:Page:Page loading complete.</pre>
* Occurred at 11:59:25 local time and 806 milliseconds. It's priority was <code>INFO</code>,
* it occurred in the category <i>Page</i>, and the message is "Page loading complete.".
* <P>
* Each logging <i>category</i> has a <i>priority</i> associated with it. If a message's
* priority is lower than the current priority for the category it is logged in, the
* message will be suppressed (will not appear in the "Results" pane).
* <p>
* It is critical to be familiar with the diagnostic categories built-in to Smart GWT -
* you will use them in most debugging sessions. Open the Logging Preferences menu and select
* "More.." to see a list of diagnostic log categories. Hover over each category name to
* see a description of what kind of messages are logged in the category.
* <P>
* <h4>Debugging JavaScript Errors</h4>
* <P>
* Javascript errors will typically be reported in the Developer Console. Wherever possible a stack
* trace will be included which can help determine the cause of the error.
* In addition to this, recent versions of the Firefox browser (versions 6.0 and above) ship with some
* useful development tools including the Error Console for reporting errors. We also recommend Console2
* and Firebug for debugging in Firefox.
* <P>
* In Internet Explorer, when JS errors occur, Smart GWT is able to report full stack traces
* in the Developer Console. This can be invaluable when your code triggers a JS error
* in the Smart GWT libraries themselves, or when it is unclear how your code is being
* called. Stack traces from Internet Explorer should <i>always</i> be included in issue
* reports sent to Isomorphic Software, if at all possible.
* <P>
* <h4>Inspecting application state</h4>
* <P>
* The "Evaluate JS Expression" area of the Results Pane in the Developer Console can be used
* to inspect the current state of a Smart GWT application. Any Smart GWT or browser
* built-in API can be called from the "Evaluate JS Expression" area, and the results will
* be intelligently summarized (via Log.echo). For example, simply typing a
* component's ID and pressing the "Eval JS" button will give you a dump of it's current
* property values.
* <P>
* Many, many Smart GWT APIs can be usefully called while troubleshooting, eg,
* {@link com.smartgwt.client.widgets.grid.ListGrid#getData data} is a {@link com.smartgwt.client.data.ResultSet} when a
* grid is DataBound and
* {@link com.smartgwt.client.data.ResultSet#get ResultSet.get} can be called to inspect the current values on records. In
* addition,
* new application code can be tried out, for example, you might repeatedly instantiate a new
* component, trying variants on the properties you could give it.
* <P>
* <b>Inspecting transient application state with logs</b>
* <P>
* Transient state, such as the values of local variables in a method that is crashing, can be
* sent to the Developer Console via using the Log class. For example, to dump the
* value of the local variable "request":
* <pre>
* isc.logWarn("request is: " + isc.echo(request));
* </pre>
* <P>
* It's a good idea to dump the values of local variables in any method that is crashing or
* behaving unexpectedly.
* <P>
* Note the use of {@link com.smartgwt.client.util.isc#logWarn logWarn()} above: in typical debugging sessions,
* it's best
* to simply use <code>logWarn</code> method to output diagnostics to ensure your message will
* not be suppressed by log priority settings.
* <P>
* NOTE: never use the native <code>alert()</code> method to output diagnostics. Among other
* issues, <code>alert()</code> can affect timing, masking or altering the behavior you were
* trying to debug. Smart GWT's logging system doesn't suffer from these problems and
* provides much more control.
* <P>
* <h4>Issue Reports</h4>
* <P>
* If you believe you've discovered a bug in Smart GWT or you are having trouble using
* Smart GWT APIs, you can report it at <a href='http://forums.smartclient.com/'
* onclick="window.open('http://forums.smartclient.com/');return false;">http://forums.smartclient.com/</a>, or, if
* you have Enterprise Support, at the
* <a href='http://support.isomorphic.com/' onclick="window.open('http://support.isomorphic.com/');return false;">Customer
* Support Extranet</a>.
* <P>
* <b>How quickly your issue is resolved is entirely up to you</b>. If you follow the steps
* below and submit an appropriate issue report, you will generally receive a rapid solution
* from Isomorphic Support, regardless of what support level you have, because Isomorphic
* aggressively corrects bugs and legitimate usage issues. If you skip steps you are likely to
* be directed back to this document and asked to submit a more complete issue report.
* <P>
* Before reporting an issue, ensure that you:
* <ul>
* <li> Have read the ${isc.DocUtils.linkForDocNode('QuickStartGuide', 'QuickStart Guide')} cover to
* cover. Later chapters cover more advanced topics and provide links to further examples and
* reference.
* <li> Have searched the ${isc.DocUtils.linkForDocNode('FeatureExplorer', 'Feature Explorer')} for examples that show
* what you are trying to do
* <li> Have searched this reference, trying multiple searches using different, common and
* related terms for what you are trying to do (eg for search, try "search", "filter",
* "criteria", "find", "match", etc)
* <li> Have searched the public <a href='http://forums.smartclient.com'
* onclick="window.open('http://forums.smartclient.com');return false;">forums</a>
* </ul>
* Always include:
* <ul>
* <li> A description of what you are trying to accomplish <b>from a user's perspective</b>.
* The best answers often point out a simpler approach.
* <li> The browser(s), operating system(s) and Smart GWT version(s) you experience the error
* on (Smart GWT version is available in the lower-left handle corner of the Developer
* Console)
* </ul>
* Then, include <b>either</b> a standalone test case (see below), <b>or</b>:
* <ul>
* <li> For JS errors, Stack traces from Firebug (for Firefox) or the Developer Console (for
* IE), as covered under "Debugging JavaScript Errors" above
* <li> Results of calling <code>echo()</code> on local variables or other application
* state you think is relevant (see "Inspecting Application State" above)
* <li> What server platform and {@link com.smartgwt.client.docs.ClientServerIntegration databinding approach} you
* are using, if applicable
* <li> contents of the Smart GWT Developer Console "Log messages" area, with appropriate
* diagnostic categories set the DEBUG or INFO level (see "Built-in Diagnostics" above)
* <li> sample code and sample data
* </ul>
* <b>Preparing a standalone test case</b>
* <P>
* A standalone test case is one of:
* <ol>
* <li> a chunk of JavaScript code that can be executed from the "Eval JS" area of the
* Developer Console on some specified page within the unmodified Smart GWT SDK,
* demonstrating your issue
* <li> an .html or .jsp file that can be dropped at a specified location into an unmodified
* Smart GWT SDK and will run without changes, demonstrating your issue.
* <li> a .zip file that includes a standalone .html/.jsp file as above, as well as
* dependencies required to make the test case runnable, such as XML datasets
* </ol>
* <P>
* Submitting a standalone test case removes any ambiguity as to whether there is a bug in
* Smart GWT or a bug in your code, and eliminates the possibility of Isomorphic Support
* responding with a "works for me" result due to incomplete information. Issues with verified
* test cases are routed directly to the engineer that authored the relevant Smart GWT
* subsystem, often as the new highest priority task. In addition, the process of preparing a
* test case very often allows you to solve the issue yourself.
* <P>
* There are two approaches to test case preparation:
* <ol>
* <li> Add code to an existing Smart GWT example until you can reproduce the problem
* <li> Remove code from your application until it minimally shows the problem and runs standalone
* </ol>
* <P>
* For approach #1, find the nearest match to your use case in the
* ${isc.DocUtils.linkForDocNode('FeatureExplorer')} examples or in the other examples accessible from the Examples
* folder of the SDK, then try to minimally modify that example to demonstrate your issue.
* Feature Explorer examples are a particularly good starting point because you can simply copy
* the code from the Feature Explorer to the Eval JS area of the Developer Console and begin
* changing it, and if successful this yields a type #1 test case, the easiest for you to
* submit and most efficient for Isomorphic to work with.
* <P>
* For approach #2,
* <ol>
* <li> If a server is involved in initial page generation (eg a .jsp file), in most cases you
* can eliminate many server dependencies <b>and</b> create an easily modifiable starting point
* by using the browser's "View Source" feature to save a copy of the generated HTML output as
* an .html file in the same directory as the .jsp file that generated it. Such a file will
* generally continue to function (all relative paths are still correct), and can be modified
* freely without the need to later revert changes to a .jsp.
* <li> Eliminate any code that isn't involved in the interaction. Keep running the test case
* as you eliminate code to ensure you are still seeing the issue (you may solve it this way,
* or find key preconditions that you can report to Isomorphic)
* <li> For any issue that isn't cosmetic, revert to a default Smart GWT skin
* <li> For any necessary RPC/DataSource interactions, spoof the interaction with one of these
* approaches:
* <ul>
* <li> switch any DataSources to one of the sample DataSources from the SDK (eg "supplyItem")
* if your issue can still be reproduced in this case.
* <li> create a small sample dataset in JavaScript directly in the .html file, and use a
* {@link com.smartgwt.client.data.DataSource#getClientOnly clientOnly DataSource} with that dataset.
* <li> capture server responses verbatim by setting the RPCManager log category to DEBUG, save
* the responses as flat files, and set {@link com.smartgwt.client.data.DataSource#getDataURL dataURL} to point at them.
* <li> for RPCs, instead of calling the RPCManager, directly call your own callback function,
* passing a spoofed RPCResponse that includes just the fields your code depends upon
* </ul>
* <li> Finally, move your .html file into the stock Smart GWT SDK along with any remaining
* dependencies and verify the problem can still be reproduced
* </ol>
* Having prepared the test case, combine it with the other required issue report information
* covered above, and submit it to the <a href='http://forums.smartclient.com/'
* onclick="window.open('http://forums.smartclient.com/');return false;">forums</a>,
* or, if you have Enterprise Support, at the
* <a href='http://support.isomorphic.com/' onclick="window.open('http://support.isomorphic.com/');return false;">Customer
* Support Extranet</a>.
* <P>
* <h4>Adding your own diagnostic categories</h4>
* <P>
* Calling <code>logWarn()</code> is fine for a log statement you plan to delete at the end of
* the debugging session. However, many log statements have lasting value if you could enable
* or disable them only when you need the relevant diagnostics, like Smart GWT's built-in
* diagnostic categories. To do this, pick a priority level less than <code>WARN</code>
* (<code>INFO</code> or <code>DEBUG</code>), and call the corresponding method on the Log
* class (<code>logInfo()</code> or <code>logDebug()</code>), passing the category name as a
* second parameter. For example:
* <pre>
* isc.Log.logInfo("first record is: " +
* isc.Log.echo(myGrid.data.get(0)),
* "myGridLoading");
* </pre>
* This message will no longer appear in the Results Pane by default, because its priority
* (<code>INFO</code>) is less than the default of <code>WARN</code>. To see this message,
* open the Logging Preferences menu and pick "More..", then click the "Add" button, enter
* "myGridLoading" as the category name and set the priority to <code>INFO</code>. The message
* will now appear next time it is logged.
* <P>
* Now you have a custom log category that you and other developers can use to debug your
* application, subsystem by subsystem. These diagnostics will be available to you both in
* development and production environments.
* <P>
* As with Smart GWT's built-in diagnostics, you may choose to log certain messages in your
* custom category at the <code>DEBUG</code> level and a lesser number of messages at the
* <code>INFO</code> level, to create different depths of diagnostic output.
* <P>
* <h4>Logging refinements</h4>
* <P>
* The core log methods (<code>logDebug()</code>, <code>logInfo()</code>,
* <code>logWarn()</code>) and the "echo" facilities (<code>echo()</code> and
* <code>echoAll()</code>) are available on every Smart GWT component and Class. Hence,
* in many cases, the special JavaScript value "this" will refer to an object that supports
* <code>logWarn()</code> et al. For example:
* <pre>
* Canvas.create({
* ID:"canvasExample",
* contents:"Hello World!",
* click:"this.logWarn('the Canvas is: ' + this.echo(this))"
* });
* </pre>
* The special value "this" is not always set to a Smart GWT component, for example, in some
* kinds of callbacks (eg {@link com.smartgwt.client.widgets.grid.ListGrid#fetchData fetchData()}). When in doubt, use
* these
* methods via the Log class as <code>isc.Log.logWarn()</code>.
* <P>
* <b>Logging performance</b>
* <P>
* Because the log message is actually formed <i>before</i> the call to the log system, logs
* that are suppressed can still carry a performance penalty. This is particularly true of
* logs that output a lot of data or occur frequently. To avoid this penalty, you can check in
* advance whether a message will be suppressed using
* isc.Log.logIsDebugEnabled() and
* isc.Log.logIsInfoEnabled(). For example:
* <pre>
* if (isc.Log.logIsInfoEnabled("myGridLoading")) {
* isc.Log.logInfo("first record is: " +
* isc.Log.echo(myGrid.data.get(0)),
* "myGridLoading");
* }
* </pre>
* Generally, it is only important to do this for logs that will occur multiple times during a
* given user interaction (eg a mousedown or keypress) and/or that call <code>echo()</code> on
* objects with many properties.
*/
public interface Debugging {
}