Skip to content

Commit 86cdb86

Browse files
authored
Add more logging and add recovery from bad state (microsoft#5319)
Part of microsoft#5277
1 parent f6a371b commit 86cdb86

File tree

3 files changed

+59
-6
lines changed

3 files changed

+59
-6
lines changed

scripts/prepare-nightly-build.js

+6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
16
const fs = require('fs');
27
const argv = require('minimist')(process.argv.slice(2));
38

@@ -15,6 +20,7 @@ function prependZero(number) {
1520

1621
// update name, publisher and description
1722
// calculate version
23+
// If the format of the patch version is ever changed, the isPreRelease utility function should be updated.
1824
let patch = argv['v'];
1925
if (typeof patch !== 'string') {
2026
const date = new Date();

src/common/utils.ts

+14-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { sep } from 'path';
88
import dayjs from 'dayjs';
99
import * as relativeTime from 'dayjs/plugin/relativeTime';
1010
import * as updateLocale from 'dayjs/plugin/updateLocale';
11-
import type { Disposable, Event, Uri } from 'vscode';
11+
import type { Disposable, Event, ExtensionContext, Uri } from 'vscode';
1212
// TODO: localization for webview needed
1313

1414
dayjs.extend(relativeTime.default, {
@@ -710,6 +710,19 @@ export class UriIterator implements IKeyIterator<Uri> {
710710
}
711711
}
712712

713+
export function isPreRelease(context: ExtensionContext): boolean {
714+
const uri = context.extensionUri;
715+
const path = uri.path;
716+
const lastIndexOfDot = path.lastIndexOf('.');
717+
if (lastIndexOfDot === -1) {
718+
return false;
719+
}
720+
const patchVersion = path.substr(lastIndexOfDot + 1);
721+
// The patch version of release versions should never be more than 1 digit since it is only used for recovery releases.
722+
// The patch version of pre-release is the date + time.
723+
return patchVersion.length > 1;
724+
}
725+
713726
class TernarySearchTreeNode<K, V> {
714727
segment!: string;
715728
value: V | undefined;

src/view/reviewManager.ts

+39-5
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import {
2525
} from '../common/settingKeys';
2626
import { ITelemetry } from '../common/telemetry';
2727
import { fromPRUri, fromReviewUri, KnownMediaExtensions, PRUriParams, Schemes, toReviewUri } from '../common/uri';
28-
import { formatError, groupBy, onceEvent } from '../common/utils';
28+
import { formatError, groupBy, isPreRelease, onceEvent } from '../common/utils';
2929
import { FOCUS_REVIEW_MODE } from '../constants';
3030
import { GitHubCreatePullRequestLinkProvider } from '../github/createPRLinkProvider';
3131
import { FolderRepositoryManager } from '../github/folderRepositoryManager';
@@ -267,9 +267,40 @@ export class ReviewManager {
267267
}
268268
}
269269

270+
private hasShownLogRequest: boolean = false;
270271
private async validateStatueAndSetContext(silent: boolean, updateLayout: boolean) {
271-
await this.validateState(silent, updateLayout);
272-
await vscode.commands.executeCommand('setContext', 'github:stateValidated', true);
272+
// TODO @alexr00: There's a bug where validateState never returns sometimes. It's not clear what's causing this.
273+
// This is a temporary workaround to ensure that the validateStatueAndSetContext promise always resolves.
274+
// Additional logs have been added, and the issue is being tracked here: https://github.com/microsoft/vscode-pull-request-git/issues/5277
275+
let timeout: NodeJS.Timeout | undefined;
276+
const timeoutPromise = new Promise<void>(resolve => {
277+
timeout = setTimeout(() => {
278+
if (timeout) {
279+
clearTimeout(timeout);
280+
timeout = undefined;
281+
Logger.error('Timeout occurred while validating state.', ReviewManager.ID);
282+
if (!this.hasShownLogRequest && isPreRelease(this._context)) {
283+
this.hasShownLogRequest = true;
284+
vscode.window.showErrorMessage(vscode.l10n.t('A known error has occurred refreshing the repository state. Please share logs from "GitHub Pull Request" in the [tracking issue]({0}).', 'https://github.com/microsoft/vscode-pull-request-github/issues/5277'));
285+
}
286+
}
287+
resolve();
288+
}, 1000 * 60 * 2);
289+
});
290+
291+
const validatePromise = new Promise<void>(resolve => {
292+
this.validateState(silent, updateLayout).then(() => {
293+
vscode.commands.executeCommand('setContext', 'github:stateValidated', true).then(() => {
294+
if (timeout) {
295+
clearTimeout(timeout);
296+
timeout = undefined;
297+
}
298+
resolve();
299+
});
300+
});
301+
});
302+
303+
return Promise.race([validatePromise, timeoutPromise]);
273304
}
274305

275306
private async offerIgnoreBranch(currentBranchName): Promise<boolean> {
@@ -388,8 +419,10 @@ export class ReviewManager {
388419
const previousPrNumber = this._prNumber;
389420
let pr = await this.resolvePullRequest(matchingPullRequestMetadata);
390421
if (!pr) {
422+
Logger.appendLine(`Unable to resolve PR #${matchingPullRequestMetadata.prNumber}`, ReviewManager.ID);
391423
return;
392424
}
425+
Logger.appendLine(`Resolved PR #${matchingPullRequestMetadata.prNumber}, state is ${pr.state}`, ReviewManager.ID);
393426

394427
// Check if the PR is open, if not, check if there's another PR from the same branch on GitHub
395428
if (pr.state !== GithubItemStateEnum.Open) {
@@ -416,14 +449,14 @@ export class ReviewManager {
416449
.get<{ merged: boolean, closed: boolean }>(USE_REVIEW_MODE, { merged: true, closed: false });
417450

418451
if (pr.isClosed && !useReviewConfiguration.closed) {
419-
await this.clear(true);
420452
Logger.appendLine('This PR is closed', ReviewManager.ID);
453+
await this.clear(true);
421454
return;
422455
}
423456

424457
if (pr.isMerged && !useReviewConfiguration.merged) {
425-
await this.clear(true);
426458
Logger.appendLine('This PR is merged', ReviewManager.ID);
459+
await this.clear(true);
427460
return;
428461
}
429462

@@ -471,6 +504,7 @@ export class ReviewManager {
471504
this._changesSinceLastReviewProgress.endProgress();
472505
})
473506
);
507+
Logger.appendLine(`Register in memory content provider`, ReviewManager.ID);
474508
await this.registerGitHubInMemContentProvider();
475509

476510
this.statusBarItem.text = '$(git-pull-request) ' + vscode.l10n.t('Pull Request #{0}', pr.number);

0 commit comments

Comments
 (0)