提交 facb0e54 编写于 作者: T Tomas Vik

feat: better error reporting for fetching project and current user

上级 76088fbd
......@@ -105,6 +105,10 @@
"command": "gl.validateCIConfig",
"title": "GitLab: Validate GitLab CI config"
},
{
"command": "gl.showOutput",
"title": "GitLab: Show extension logs"
},
{
"command": "gl.refreshSidebar",
"title": "GitLab: Refresh sidebar",
......
......@@ -21,6 +21,7 @@ class DataProvider {
try {
this.project = await gitLabService.fetchCurrentProject(workspaceFolder);
} catch (e) {
vscode.gitLabWorkflow.log(e.detail);
this.project = null;
this.children.push(
new SidebarTreeItem('No pipeline found.'),
......
/* eslint-disable max-classes-per-file */
const { StatusCodeError } = require('request-promise/errors');
class ApiError extends Error {
constructor(error, action) {
super(error);
this.action = action;
this.message = `API request failed when trying to ${this.action} because: ${error.message}`;
this.originalError = error;
}
get requestDetails() {
if (!(this.originalError instanceof StatusCodeError)) return {};
const { method, url } = this.originalError.options;
const { response } = this.originalError;
return {
request: { method, url },
response,
};
}
get details() {
const { message, stack } = this;
return JSON.stringify(
{
message,
stack: stack && stack.split('\n'),
...this.requestDetails,
},
null,
2,
);
}
}
module.exports = {
ApiError,
};
......@@ -11,9 +11,22 @@ const webviewController = require('./webview_controller');
const IssuableDataProvider = require('./data_providers/issuable').DataProvider;
const CurrentBranchDataProvider = require('./data_providers/current_branch').DataProvider;
let context = null;
vscode.gitLabWorkflow = {
sidebarDataProviders: [],
log: () => {},
};
const wrapWithCatch = command => async () => {
try {
await command();
} catch (e) {
vscode.gitLabWorkflow.log(e.details || `${e.message}\n${e.stack}`);
const choice = await vscode.window.showErrorMessage(e.message, null, 'Show logs');
if (choice === 'Show logs') {
vscode.commands.executeCommand('gl.showOutput');
}
}
};
const registerSidebarTreeDataProviders = () => {
......@@ -30,7 +43,7 @@ const registerSidebarTreeDataProviders = () => {
register('currentBranchInfo', currentBranchDataProvider);
};
const registerCommands = () => {
const registerCommands = (context, outputChannel) => {
const commands = {
'gl.showIssuesAssignedToMe': openers.showIssues,
'gl.showMergeRequestsAssignedToMe': openers.showMergeRequests,
......@@ -51,25 +64,23 @@ const registerCommands = () => {
'gl.validateCIConfig': ciConfigValidator.validate,
'gl.refreshSidebar': sidebar.refresh,
'gl.showRichContent': webviewController.create,
'gl.showOutput': () => outputChannel.show(),
};
Object.keys(commands).forEach(cmd => {
context.subscriptions.push(vscode.commands.registerCommand(cmd, commands[cmd]));
context.subscriptions.push(vscode.commands.registerCommand(cmd, wrapWithCatch(commands[cmd])));
});
registerSidebarTreeDataProviders();
};
const init = () => {
const activate = context => {
const outputChannel = vscode.window.createOutputChannel('GitLab Workflow');
vscode.gitLabWorkflow.log = line => outputChannel.appendLine(line);
registerCommands(context, outputChannel);
webviewController.addDeps(context);
tokenService.init(context);
};
const activate = ctx => {
context = ctx;
registerCommands();
init();
};
exports.init = init;
exports.activate = activate;
......@@ -5,6 +5,7 @@ const GitService = require('./git_service');
const tokenService = require('./token_service');
const statusBar = require('./status_bar');
const gitlabProjectInput = require('./gitlab_project_input');
const { ApiError } = require('./errors');
const projectCache = [];
let versionCache = null;
......@@ -149,7 +150,15 @@ async function fetchCurrentProject(workspaceFolder) {
return await fetchProjectData(remote);
} catch (e) {
console.error(e);
throw new ApiError(e, 'get current project');
}
}
async function fetchCurrentProjectSwallowError(workspaceFolder) {
try {
return fetchCurrentProject(workspaceFolder);
} catch (error) {
vscode.gitLabWorkflow.log(error.detail);
return null;
}
}
......@@ -171,11 +180,7 @@ async function fetchCurrentUser() {
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;
throw new ApiError(e, 'get current user');
}
}
......@@ -208,7 +213,7 @@ async function getAllGitlabProjects() {
let workspaceFolders = [];
if (vscode.workspace.workspaceFolders) {
workspaceFolders = vscode.workspace.workspaceFolders.map(workspaceFolder => ({
label: fetchCurrentProject(workspaceFolder.uri.fsPath),
label: fetchCurrentProjectSwallowError(workspaceFolder.uri.fsPath),
uri: workspaceFolder.uri.fsPath,
}));
......@@ -292,7 +297,7 @@ async function fetchIssuables(params = {}, projectUri) {
return [];
}
const project = await fetchCurrentProject(projectUri);
const project = await fetchCurrentProjectSwallowError(projectUri);
if (project) {
if (config.type === 'vulnerabilities' && config.scope !== 'dismissed') {
config.scope = 'all';
......@@ -455,7 +460,7 @@ async function fetchLastJobsForCurrentBranch(pipeline, workspaceFolder) {
}
async function fetchOpenMergeRequestForCurrentBranch(workspaceFolder) {
const project = await fetchCurrentProject(workspaceFolder);
const project = await fetchCurrentProjectSwallowError(workspaceFolder);
const branchName = await createGitService(workspaceFolder).fetchTrackingBranchName();
const path = `/projects/${project.id}/merge_requests?state=opened&source_branch=${branchName}`;
......@@ -476,7 +481,7 @@ async function fetchOpenMergeRequestForCurrentBranch(workspaceFolder) {
*/
async function handlePipelineAction(action, workspaceFolder) {
const pipeline = await fetchLastPipelineForCurrentBranch(workspaceFolder);
const project = await fetchCurrentProject(workspaceFolder);
const project = await fetchCurrentProjectSwallowError(workspaceFolder);
if (pipeline && project) {
let endpoint = `/projects/${project.id}/pipelines/${pipeline.id}/${action}`;
......@@ -503,7 +508,7 @@ async function handlePipelineAction(action, workspaceFolder) {
}
async function fetchMRIssues(mrId, workspaceFolder) {
const project = await fetchCurrentProject(workspaceFolder);
const project = await fetchCurrentProjectSwallowError(workspaceFolder);
let issues = [];
if (project) {
......@@ -626,7 +631,7 @@ async function renderMarkdown(markdown, workspaceFolder) {
}
try {
const project = await fetchCurrentProject(workspaceFolder);
const project = await fetchCurrentProjectSwallowError(workspaceFolder);
const { response } = await fetch('/markdown', 'POST', {
text: markdown,
project: project.path_with_namespace,
......@@ -662,6 +667,7 @@ exports.fetchOpenMergeRequestForCurrentBranch = fetchOpenMergeRequestForCurrentB
exports.fetchLastPipelineForCurrentBranch = fetchLastPipelineForCurrentBranch;
exports.fetchLastJobsForCurrentBranch = fetchLastJobsForCurrentBranch;
exports.fetchCurrentProject = fetchCurrentProject;
exports.fetchCurrentProjectSwallowError = fetchCurrentProjectSwallowError;
exports.fetchCurrentPipelineProject = fetchCurrentPipelineProject;
exports.handlePipelineAction = handlePipelineAction;
exports.fetchMRIssues = fetchMRIssues;
......
......@@ -3,9 +3,7 @@ const GitService = require('./git_service');
const gitLabService = require('./gitlab_service');
const tokenService = require('./token_service');
const openUrl = url => {
vscode.commands.executeCommand('vscode.open', vscode.Uri.parse(url));
};
const openUrl = url => vscode.commands.executeCommand('vscode.open', vscode.Uri.parse(url));
const createGitService = workspaceFolder =>
new GitService(workspaceFolder, vscode.workspace.getConfiguration('gitlab'), tokenService);
......@@ -25,36 +23,23 @@ const createGitService = workspaceFolder =>
*/
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);
}
async function openLink(link, workspaceFolder) {
openUrl(await getLink(link, workspaceFolder));
async function openLink(linkTemplate, workspaceFolder) {
await openUrl(await getLink(linkTemplate, workspaceFolder));
}
async function showIssues() {
const workspaceFolder = await gitLabService.getCurrentWorkspaceFolderOrSelectOne();
openLink('$projectUrl/issues?assignee_id=$userId', workspaceFolder);
await openLink('$projectUrl/issues?assignee_id=$userId', workspaceFolder);
}
async function showMergeRequests() {
const workspaceFolder = await gitLabService.getCurrentWorkspaceFolderOrSelectOne();
openLink('$projectUrl/merge_requests?assignee_id=$userId', workspaceFolder);
await openLink('$projectUrl/merge_requests?assignee_id=$userId', workspaceFolder);
}
async function getActiveFile() {
......@@ -62,7 +47,7 @@ async function getActiveFile() {
const workspaceFolder = vscode.workspace.getWorkspaceFolder(editor.document.uri).uri.fsPath;
if (editor) {
const currentProject = await gitLabService.fetchCurrentProject(workspaceFolder);
const currentProject = await gitLabService.fetchCurrentProjectSwallowError(workspaceFolder);
if (currentProject) {
const branchName = await createGitService(workspaceFolder).fetchTrackingBranchName();
......@@ -91,7 +76,7 @@ async function getActiveFile() {
}
async function openActiveFile() {
openUrl(await getActiveFile());
await openUrl(await getActiveFile());
}
async function copyLinkToActiveFile() {
......@@ -104,7 +89,7 @@ async function openCurrentMergeRequest() {
const mr = await gitLabService.fetchOpenMergeRequestForCurrentBranch(workspaceFolder);
if (mr) {
openUrl(mr.web_url);
await openUrl(mr.web_url);
}
}
......@@ -156,12 +141,8 @@ async function compareCurrentBranch() {
let lastCommitId = null;
const workspaceFolder = await gitLabService.getCurrentWorkspaceFolderOrSelectOne();
try {
project = await gitLabService.fetchCurrentProject(workspaceFolder);
lastCommitId = await createGitService(workspaceFolder).fetchLastCommitId();
} catch (e) {
console.log('Failed to run compareCurrentBranch command', e);
}
project = await gitLabService.fetchCurrentProject(workspaceFolder);
lastCommitId = await createGitService(workspaceFolder).fetchLastCommitId();
if (project && lastCommitId) {
openUrl(`${project.web_url}/compare/master...${lastCommitId}`);
......
......@@ -95,7 +95,7 @@ async function showSearchInputFor(noteableType) {
const workspaceFolder = await gitLabService.getCurrentWorkspaceFolderOrSelectOne();
const queryString = await parseQuery(query, noteableType);
const project = await gitLabService.fetchCurrentProject(workspaceFolder);
const project = await gitLabService.fetchCurrentProjectSwallowError(workspaceFolder);
if (project) {
openers.openUrl(`${project.web_url}/${noteableType}${queryString}`);
......
......@@ -68,7 +68,7 @@ async function showPicker() {
if (editor) {
workspaceFolder = await gitLabService.getCurrenWorkspaceFolder();
project = await gitLabService.fetchCurrentProject(workspaceFolder);
project = await gitLabService.fetchCurrentProjectSwallowError(workspaceFolder);
if (project == null) {
workspaceFolder = await gitlabProjectInput.show(
......@@ -80,7 +80,7 @@ async function showPicker() {
],
"Select a Gitlab Project or use the User's Snippets",
);
project = await gitLabService.fetchCurrentProject(workspaceFolder);
project = await gitLabService.fetchCurrentProjectSwallowError(workspaceFolder);
}
const visibility = await vscode.window.showQuickPick(visibilityOptions);
......
......@@ -143,7 +143,7 @@ async function fetchBranchMR() {
try {
workspaceFolder = vscode.workspace.getWorkspaceFolder(editor.document.uri).uri.fsPath;
project = await gitLabService.fetchCurrentProject(workspaceFolder);
project = await gitLabService.fetchCurrentProjectSwallowError(workspaceFolder);
if (project != null) {
mr = await gitLabService.fetchOpenMergeRequestForCurrentBranch(workspaceFolder);
mrStatusBarItem.show();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册