Debug your extension with Visual Studio Code

Completed

The process of finding and correcting errors is called debugging. With Visual Studio Code and the AL Language extension, you get an integrated debugger to help you inspect your code to verify that your application can run as expected. To start a debugging session, press the F5 key.

Keep in mind the following limitations:

  • External code can only be debugged if the code has the showMyCode flag set. You can set the showMyCode flag in the app.json configuration file.

  • The debugger launches a new client instance each time you press the F5 key. If you close the debugging session and then start a new session, the new session will rely on a new client instance. We recommend that you close the web client instances when you close a debugging session.

  • Pausing the debugging session is not supported.

Breakpoints

The basic concept in debugging is the breakpoint, which is a mark that you set on a statement. When the program flow reaches the breakpoint, the debugger stops running until you instruct it to continue. Without any breakpoints, the code runs without interruption when the debugger is active. You can set a breakpoint by using the Debug menu in Visual Studio Code, or you can press F9 on the line that you want to debug.

You can step into the base application code by using the Go to Definition feature and set breakpoints on the referenced code, which is generally a (.dal) file. To set a breakpoint on the external code or base application code, complete the following steps.

  1. Create a variable of a base object or select the SourceTable on a page.

  2. Right-click the variable and select Go to Definition, or you can press F12. An external file (.dal file) will open.

  3. Select the line where you'd like to put a breakpoint and then press F9.

Debugging shortcuts

While debugging, you can use a few shortcuts to start or stop debugging or to step over or into the code.

  • F5 - Start debugging

  • Ctrl+F5 - Start without debugging

  • Shift+F5 - Stop debugging

  • Ctrl+Shift+F5 - Start debugging without publishing. The debugger will debug the last published version, not the version that is active in your Visual Studio Code environment.

  • Alt+F5 - Start Rapid Application Development with debugging

  • F10 - Step over

  • F11 - Step into

  • Shift+F11 - Step out

  • F12 - Go to Definition

Break on errors

In the launch.json configuration file, you can specify if the debugger should break on the next error by using the breakOnError property. If the debugger is set to breakOnError, then it stops running on errors that are handled in code and on unhandled errors.

The default value of the breakOnError property is true, which means that the debugger stops an implementation that throws an error by default. To skip the error handling process, set the breakOnError property to false in the launch.json file.

The breakOnError setting in the launch.json file takes one of the following values:

  • true - Breaks on all errors.

  • false - Doesn't break on any errors.

  • None - Doesn't break on any errors.

  • All - Breaks on all errors.

  • ExcludeTry - Breaks on errors only if they occur outside of the context of a Try function.

The values true and false are being currently retained for backward compatibility. They map to All and None. We recommend using the latter going forward. True and false might become obsolete in a future version.

Break on record changes

In the launch.json configuration file, you can specify if the debugger breaks on record changes by using the breakOnRecordWrite property. If the debugger is set to break on record changes, then it breaks before creating, modifying, or deleting a record.

The default value of the breakOnRecordWrite property is false, which means that the debugger isn't set to break on record changes by default. To break on record changes, set the breakOnRecordWrite property to true in the launch.json file.

breakOnError and breakOnRecordWrite properties in launch.json.

The breakOnRecordWrite setting in launch.json file takes one of the following values:

  • true - Breaks on all record writes.

  • false - Doesn't break on any record writes.

  • None - Doesn't break on any record writes.

  • All - Breaks on all record writes.

  • ExcludeTemporary - Breaks on record writes only if they aren't on a temporary table.

The values true and false are being currently retained for backward compatibility. They map to All and None. We recommend using the latter going forward. True and false might become obsolete in a future version.

Resource Exposure Policy Settings

When developing an extension, your code, by default, is protected against downloading or debugging. Continue reading here below about adding Intellectual Property (IP) protection against downloading or debugging into an extension to see the source code in the extensions.

The extension development package provides a pre-configured setting for protection against viewing or downloading the code of the extensions. However, this setting can also be controlled in the manifest; the app.json file.

When you start a new project, an app.json file is generated automatically, which contains the information about the extension that you are building on. In the app.json file, you can specify a setting called resourceExposurePolicy that defines the accessibility of the resources and source code during different operations.

The resourceExposurePolicy setting specifies the following list of options:

  • allowDebugging

  • allowDownloadingSource

  • includeSourceInSymbolFile

Each of these properties defines the specific areas in which the source code of an extension can be accessed. All the options by default are set to false, which means that by default, no dependent extension can debug or download the source code of your extension.

Here is an example of a JSON file with default values when generated by using the AL: Go! Command:

... "resourceExposurePolicy": { "allowDebugging": true, "allowDownloadingSource": false, "includeSourceInSymbolFile": false }, "runtime": "8.0", "keyVaultUrls": [ "https://mykeyvault.vault.azure.net" ], "applicationInsightsConnectionString": "MyConnectionString1234" ...

The resourceExposurePolicy setting isn't visible in the app.json file when it is generated. If you want to change the default value from false, you must add the setting as shown in the syntax example above.

allowDebugging

To allow debugging in your extension, when the extension is taken as a dependency, you must set the allowDebugging flag, otherwise debugging isn't allowed. If you want to allow debuggers in your extension to view the source code, the allowDebugging property in the app.json file must be set to true.

For example, if a developer develops extension A and they or someone else on the team develops extension B, and B depends on A, then debugging B will only step into the code for A if a method from A is called and if the allowDebugging flag is set to true in the app.json file for extension A.

Unless you have specified the [NonDebuggable] attribute on methods and variables, setting the allowDebugging property to true will allow stepping into this code. If you, however, have marked the methods and variables marked with the [NonDebuggable] attribute, these will remain non-debuggable.

The default value of the allowDebugging flag is false. It's recommended that you only set this flag to true if you trust who is extending your extension. If allowDebugging is set to true, anyone who extends your code has access to debug into it. If you want to allow only some individuals to have access to your code, you can override the resource policy.

There are a few cases where code can be debugged into despite the allowDebugging flag being set to false. These are:

  • Someone will still be able to view your code if an extension is deployed through Visual Studio Code as a DEV extension, as opposed to deployed using a cmdlet, by using the Extension Management page in Business Central or by using AppSource.

  • Custom external tools for AL might get access to the DAL information exposed by the debugger by listening to debugger events triggered by Visual Studio Code.

allowDownloadingSource

When this setting is set to true in the app.json file of extension A, the source code and any media files of extension A can be downloaded. For example, from the Download Source option in the Extension Management page in Business Central. Extension A can be a PTE or a DEV extension. The default value of allowDownloadingSource is false.

includeSourceInSymbolFile

When this is set to true in the app.json file of extension A, the downloaded symbol file in Visual Studio Code which is accessed by using the Downloading Symbols functionality, contains symbols, source code, and all other resources of extension A. Go to Definition to view the code also depends on this property. The default value of includesourceInSymbolFile is false.

AL compiler diagnostic messages

When you compile or run code analyzers, diagnostic messages can appear in the form of error, warning, or informational messages. To help resolve such diagnostic issues, these now contain a URL for additional documentation on what is causing the issue and options for how to resolve the issue.

Having links in diagnostic messages from compilation or code analyzers will support linking to additional, relevant documentation about the cause of the issue as well as options for how to resolve it.

There are documentation pages for all diagnostic issues and URL links from compiler output diagnostics. Still, in the beginning, the documentation will be very shallow and mainly contain the message. We ask partners to help with feedback on which topics to prioritize more documentation on, and also share feedback on what content would be useful to help resolve issues. Based on this, the documentation will hopefully grow over time, and the knowledge among partners will be shared through these tips and tricks on causes and fixes, lowering the time spent on each diagnostic.

You can view the current AL Compiler Diagnostics article for examples and reference.

Launch in a specific company from Visual Studio Code

You can have multiple companies in a Business Central tenant. When you debug or test your app, you often want to do this in the context of a specific company. In earlier versions of Business Central, you couldn't control which company to use when you launched the client from Visual Studio Code. Typically, you would have to set up the default company in the client first.

A new startupCompany parameter was added to the Visual Studio Code launch.json configuration file. Use it to specify the company to use when the client is launched from Visual Studio Code, such as when you run or debug.

View SQL Server information during AL debugging

Understanding database locks when developing and troubleshooting in cloud sandboxes without direct SQL access can be hard. It can be difficult to identify which locks are taken from AL when calling, for example, the rec.Modify() or rec.FindSet() methods. While SQL locks can now be seen in the web client, using this for debugging is cumbersome because you need another browser with another session.

To help with this, the Database Statistics section in the Variables window for the Visual Studio Code AL debugging experience has been extended to show SQL locks for the debugged session.

In addition to the last executed SQL statements and database statistics, you can also get information about active SQL locks occurring during the session, which is being debugged. The list is updated when stepping through AL code. Commits will remove the held locks.