-
Notifications
You must be signed in to change notification settings - Fork 25
Integrate Your Plugin With the Doctor Command
Salesforce CLI includes the doctor
command that you can run when you're having issues with the CLI. The command inspects your CLI installation and environment, runs diagnostic tests, provides suggestions, and writes the data to a local diagnostic file.
To help your users troubleshoot problems with your plugin, you can integrate it into the doctor
command so it runs your custom diagnostic tests. You can add custom information to both the Running all diagnostics and Suggestions sections and to the JSON results file. For example:
$ sf doctor
=== Running all diagnostics
pass - salesforcedx plugin not installed
pass - no linked plugins
pass - using latest or latest-rc CLI version
pass - YOUR CUSTOM TEST RESULTS HERE
Wrote doctor diagnosis to: /sfdx/1667932766667-diagnosis.json
=== Suggestions
* Check https://github.com/forcedotcom/cli/issues for CLI issues posted by the community.
* Check http://status.salesforce.com for general Salesforce availability and performance.
* YOUR CUSTOM SUGGESTION HERE
The main reason is to provide your users a quick and potential fix to an issue, and thus provide a better experience. Because you have a deep understanding of your plugin, you can likely predict potential problems your customers will run into. With the diagnostic tests, you can inspect their CLI and plugin configuration and suggest immediate actions if your users run into these predicted issues. If the suggestions don't fix the problem, the doctor
neatly gathers the required information that users attach to GitHub issues or provide to Salesforce Customer Support.
Writing diagnostic tests isn't a replacement for good command error handling, but rather a way to educate and clarify command usage within a complex system.
Examples of diagnostic tests include checking for:
- An environment variable that changes the behavior of your plugin or a library that your plugin uses.
- A setting within a project that changes plugin behavior.
- Required dependencies (outside of NPM) that are missing or out of date.
- A system that is required by your plugin that is unavailable.
- Anything that your customers regularly need clarification on that can't be handled directly in the commands.
See the diagnostic test in the source plugin for a real-life example. The source code for the doctor
command is here.
-
Define a hook in the
oclif
section of your plugin'spackage.json
with the following pattern, where<plugin-name>
is thename
property in yourpackage.json
file:"sf-doctor-<plugin-name>": "./path/to/compiled/hook/handler"
For example, the
plugin-source
diagnostic hook is defined with this JSON snippet; the Typescript source file and directory for the hook handler issrc/hooks/diagnostics.ts
:"oclif": { "hooks": { "sf-doctor-@salesforce/plugin-source": "./lib/hooks/diagnostics" } }
-
If your plugin is written in TypeScript, add a
devDependencies
entry inpackage.json
that points to@salesforce/plugin-info
, which contains the requiredSfDoctor
type. Use the latest version ofplugin-info
. For example:"devDependencies": { "@salesforce/plugin-info": "^2.2.7" }
-
In the hook handler source file (
src/hooks/diagnostics.ts
in our example), define and export ahook
function that runs when thedoctor
command is executed. Here's a basic Typescript example that includes one diagnostic test calledtest1
:// Import the SfDoctor interface from plugin-info and Lifecycle class from @salesforce/core import { SfDoctor } from '@salesforce/plugin-info'; import { Lifecycle } from '@salesforce/core'; // Define the shape of the hook function type HookFunction = (options: { doctor: SfDoctor }) => Promise<[void]>; // export the function export const hook: HookFunction = async (options) => { return Promise.all([test1(options.doctor)]); }; const test1 = async (doctor: SfDoctor): Promise<void> => { // Add your code for "test1" here };
-
Code the
hook
function to return the result of all your plugin's diagnostic tests usingPromise.all([test1(), test2(), test3()]);
. -
Use
doctor.addPluginData()
in your diagnostic tests to add JSON data to the fulldoctor
diagnostics report. This JSON data appears in thepluginSpecificData
section of the JSON report. For example, this code in the hook handler:const pluginName = 'my-plugin'; const prop1 = 'firstValue'; const prop2 = 'secondValue'; ... doctor.addPluginData(pluginName, { prop1, prop2, });
Results in this JSON snippet in the full
doctor
diagnostic report:"pluginSpecificData": { "my-plugin": [ { "prop1": "firstValue", "prop2": "secondValue" } ] },
-
Use the global singleton
Lifecycle
class in your diagnostic tests to include the test name and status to the top section of thedoctor
command output. For example:Lifecycle.getInstance().emit('Doctor:diagnostic', { testName, status });
You must name the event
Doctor:diagnostic
and the payload must have this shape:{ testName: string, status: string }
, wherestatus
is one of'pass' | 'fail' | 'warn' | 'unknown'
-
Use the
doctor.addSuggestion()
method in your diagnostic tests to add suggestions, based on the test results, to the bottom part of thedoctor
output. For example:doctor.addSuggestion('The environment variable ENV_VARIABLE is set, which can affect the behavior of the XX commands. Are you sure you want to set this env variable?');
-
Diagnostic tests can reference the command run by the
doctor
and all generated command output from thedoctor
diagnostics. This example comes from the diagnostic tests in@salesforce/plugin-source
:// Get the command string run by the doctor. const commandName = doctor.getDiagnosis().commandName; if (commandName?.includes('source:deploy') { /* run a test specific to that command */ } // Parse the debug.log generated by the doctor. // The code must wait for the command to execute and logs to be written. const debugLog = doctor.getDiagnosis().logFilePaths; if (debugLog?.length) { // Get the log file path, read it, look for specific output, add suggestions. }
© Copyright 2024 Salesforce.com, inc. All rights reserved. Various trademarks held by their respective owners.
- Quick Intro to Developing sf Plugins
- Get Started: Create Your First Plugin
- Design Guidelines
- Code Your Plugin
- Debug Your Plugin
- Write Useful Messages
- Test Your Plugin
- Maintain Your Plugin
- Integrate Your Plugin With the Doctor Command
- Migrate Plugins Built for sfdx
- Conceptual Overview of Salesforce CLI