feat: better error reporting for fetching project and current user
We have had many issues in the past where the extension doesn't work and at the same time, it doesn't provide users with information about the failure.
When such a failure occurs it manifests itself as a vague message that is facilitating catch-all issues like this #135 (closed).
The insufficient-error-handling is caused by two issues:
- Functions discard errors and return
null
orundefined
- Errors don't get logged or they get logged using
console
This MR is a minimal viable change that will introduce the unified concept for error handling and logging.
Problem
Most of the errors were either completely ignored or they were caught, console logged and then the failed function returned null
or undefined
Examples
git_service.js
:
try {
output = await execa.stdout(git, args, {
cwd: currentWorkspaceFolder,
preferLocal: false,
});
} catch (ex) {
// Fail siletly
}
gitlab_service.js
:
async function fetchCurrentUser() {
try {
const { response: user } = await fetch('/user');
return user;
} catch (e) {
console.error(e);
const message =
'GitLab Workflow: Cannot access current user. Check your Personal Access Token.';
vscode.window.showInformationMessage(message);
return undefined;
}
}
Which resulted in every level of the application being overly defensive:
openers.js
async function getLink(linkTemplate, workspaceFolder) {
const user = await gitLabService.fetchCurrentUser();
if (!user) {
vscode.window.showInformationMessage(
'GitLab Workflow: GitLab user not found. Check your Personal Access Token.',
);
return undefined;
}
const project = await gitLabService.fetchCurrentProject(workspaceFolder);
if (!project) {
vscode.window.showInformationMessage(
'GitLab Workflow: Failed to find file on the web. No GitLab project.',
);
return undefined;
}
return linkTemplate.replace('$userId', user.id).replace('$projectUrl', project.web_url);
}
And most of the error reporting wasn't sufficient for debugging the root cause of the problem.
Solution
Errors are going to be divided into two categories:
- non-critical: The extension can recover from such error without user intervention (e.g. using default value). These errors are only going to get logged as warnings, no message needs to be displayed to the user.
- critical: This error can't be recovered from without user intervention (configuration issues, network issues). We will show one error UI message for user action and all details are going to be logged in the extension OutputChannel (this is the subject of this MR)
I picked two often used GitLab Service methods for the initial MR: gitLabService.fetchCurrentUser()
and gitLabService.fetchCurrentProject(workspaceFolder)
. This allowed the openers.getLink()
method to be implemented in the new way and all four commands that are using it can now benefit from the improved error reportitng.
GitLab: Show issues assigned to me
GitLab: Show merge requests assigned to me
GitLab: Create new issue on current project
GitLab: Create new merge request on current project
Part of #145 (closed)