Using the Salesforce Replay Debugger With Managed Packages
This isn't rocket science, and odds are good that if you work for a Salesforce.com ISV you've already worked this out, but still, it's not really documented and it's pretty darned handy.
If you've not used it, the reply debugger can be seriously handy. It's not as good as a full debugger and has more than a few shortcomings, especially if you're used to a full debugger on other platforms, but compared to calling
System.Debug() over and over, or parsing line numbers to work out what code executed, it really can save you some time. If you're not familiar with it, checkout the official documentation to get up and running in your scratch/development orgs.
Using it as an ISV
Under the considerations section in the documentation there's this nugget:
You can use this debugger only in your orgs. ISV customer debugging is unavailable in Apex Replay Debugger. To debug customers’ orgs, use ISV Customer Debugger.
That's sort of true, but also sort of not. The caveat is that you need to have support access to the org you want to debug - once your client has granted that, login via the subscriber console in your own org, and turn on debug logging for the user in question, being sure to use
FINEST for Apex and
FINER Visualforce. Perform the action necessary to generate the log, and because you're logged in through the subscriber console you'll be able to see exactly what happened inside of yoru package. The Download button won't work when you're logged in through this context, so copy the log contents. from the UI and paste into a new file in Visual Studio Code, and save it with a
Of course, your local code might not reflect what's in the package currently installed in that org, so if you're tagging your source repo properly check out the tag for the release in question. Since semantic versioning doesn't really work so well with Salesforce's packaging constraints, our packages are versioned in a way that immediately provides some useful information - we use a
YYMM.N format, where
N is the Nth version of the package for the month specified. Checking out the third release from November last year is as simple as
git checkout 2311.3.
Once you're sure your local code is the same as that which was executed by the package and logged, you can launch the reply debugger by invoking the command palette in Visual Studio Code and choosing "SFDX: Launch Apex Reply Debugger with Current File". If you don't see that option, and only see the one for the last log file, be sure you saved the file with the
.log extension, as that appears to determine whether or not the current file option is displayed.
Now all you need to do is set some break points and hit run!
Apex language server could not provide information about valid breakpoints
Ah, this old chestnut. You might get this error when launching the debugger, and if that's the case the fix appears to be to delete the language server's cache which simply involves removing a director for the current release, something akin to the following, where 246 is the release number at the time of writing. At any rate, it'll be a directy with a number for a name.
rm -rf ./.sfdx/tools/246
After removing that directory simply restart Visual Studio Code, wait a few moments for all the plugins to intialise, and then you should be able to launch the debugger without issue.
If you're not using Visualforce this doesn't actually matter, but the Visual Studio Code plugin will complain that the log file should have been generated with Visualforce set to finest. If you have a log file where this isn't the case, but you know there's no Visualforce components in play, simply edit the top of the log file to have
VISUALFORCE,FINERand that's enough to get things moving. ↩︎
Yes, despite the fact that you're viewing the log on the screen and have therefore technically downloaded that data to your computer already, security theatre will always be security theatre. ↩︎
I'm so underwhelmed with modern computing in many ways. Our machines are doing more than ever but not seemingly faster for many things, but then you can copy several megabytes of text without even noticing it, just opening a 3MB file used to be a problem ↩︎