Skip to content

Commit

Permalink
Improve error handling
Browse files Browse the repository at this point in the history
This intends to give better error handling for velocitas init and velocitas sync
  • Loading branch information
erikbosch committed Sep 12, 2024
1 parent 81ba198 commit e5ed7aa
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 17 deletions.
33 changes: 28 additions & 5 deletions src/modules/package-downloader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,11 @@ export class PackageDownloader {
this.packageConfig = packageConfig;
}

private async _cloneRepository(packageDir: string, cloneOpts: string[]): Promise<void> {
await this.git.clone(this.packageConfig.getPackageRepo(), packageDir, cloneOpts);
private async _cloneRepository(packageDir: string, cloneOpts: string[], verbose?: boolean): Promise<void> {
const response = await this.git.clone(this.packageConfig.getPackageRepo(), packageDir, cloneOpts);
if (verbose) {
console.log(`Clone response: ${response}`);
}
}

private async _updateRepository(checkRepoAction: CheckRepoActions, verbose: boolean): Promise<void> {
Expand All @@ -49,15 +52,35 @@ export class PackageDownloader {
await this.git.checkout(branchOrTag);
}

private async _checkForValidRepo(packageDir: string, cloneOpts: string[], checkRepoAction: CheckRepoActions): Promise<void> {
private async _checkForValidRepo(
packageDir: string,
cloneOpts: string[],
checkRepoAction: CheckRepoActions,
verbose?: boolean,
): Promise<void> {
let directoryExists = CliFileSystem.existsSync(packageDir);
if (directoryExists && !(await this.isValidRepo(packageDir, checkRepoAction))) {
CliFileSystem.removeSync(packageDir);
directoryExists = false;
}

if (!directoryExists) {
await this._cloneRepository(packageDir, cloneOpts);
try {
// simple-git typically throws an error if clone fails
// but not all errors reult in an exception, for instance blocked clone due to rate limitation
// does not result in an exception
await this._cloneRepository(packageDir, cloneOpts, verbose);
} catch (error) {
if (verbose) {
console.error(error);
}
throw new Error(`Cloning of ${this.packageConfig.getPackageRepo()} failed!`);
}

// Do a second check to verify if clone seems to have succeeded
if (!(await this.isValidRepo(packageDir, checkRepoAction))) {
throw new Error(`Problem detected when cloning ${this.packageConfig.getPackageRepo()}!`);
}
}
}

Expand All @@ -80,7 +103,7 @@ export class PackageDownloader {
checkRepoAction = CheckRepoActions.IS_REPO_ROOT;
}

await this._checkForValidRepo(packageDir, cloneOpts, checkRepoAction);
await this._checkForValidRepo(packageDir, cloneOpts, checkRepoAction, verbose);
this.git = simpleGit(packageDir);
await this._updateRepository(checkRepoAction, verbose);

Expand Down
18 changes: 11 additions & 7 deletions src/modules/package.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,29 +93,33 @@ export class PackageConfig {
}

async getPackageVersions(verbose?: boolean): Promise<TagResult> {
try {
const packageInformation = await packageDownloader(this).downloadPackage({ checkVersionOnly: true, verbose: verbose });
const packageVersionTags = await packageInformation.tags();
return packageVersionTags;
const packageInformation = await packageDownloader(this).downloadPackage({ checkVersionOnly: true, verbose: verbose });
const packageVersionTags = await packageInformation.tags();
return packageVersionTags;
/*
} catch (error) {
console.log(`vvv`);
console.log(error);
console.log(`www`);
}
return {
all: [],
latest: '',
};
};*/
}

async downloadPackageVersion(verbose?: boolean): Promise<void> {
try {
await packageDownloader(this).downloadPackage({ verbose: verbose });
} catch (error) {
console.error(error);
if (verbose) {
console.error(error);
}
// If repo exist but not version we will end up with default-version
// of that repo, and on subsequent runs tooling will say that the missing version
// actually exists! To prevent this we remove the directory of the missing version!
CliFileSystem.removeSync(this.getPackageDirectoryWithVersion());
throw new Error(`Cannot find package ${this.getPackageName()}:${this.version}`);
throw new Error(`Downloading package ${this.getPackageName()}:${this.version} failed!`);
}
return;
}
Expand Down
7 changes: 5 additions & 2 deletions src/modules/projectConfig/projectConfigFileReader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,18 +46,21 @@ export class MultiFormatConfigReader implements IProjectConfigReader {
let config: ProjectConfig | null = null;

for (const reader of projectConfigReaders) {
let first: boolean = true;
try {
config = reader.read(cliVersion, path, ignoreLock);
if (config !== null) {
break;
}
} catch (error: any) {
console.warn(`Warning: ${path} not in expected format: ${error.message}, falling back to legacy format reading.`);
// This could be format error, but it could also be that repo/tag-settings are faulty, repo cannot be reached and
// similar, for example that "velocitas init" did not succeed!
console.warn(`Error reported by config reader ${reader.constructor.name}: ${error.message}`);
}
}

if (config === null) {
throw new Error(`Unable to read ${path}: unknown format!`);
throw new Error(`Unable to successfully read and interpret ${path}!`);
}

return config;
Expand Down
2 changes: 1 addition & 1 deletion src/modules/projectConfig/projectConfigLock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export class ProjectConfigLock implements ProjectConfigLockAttributes {
public findVersion(packageName: string): string {
const packageVersion = this.packages.get(packageName);
if (!packageVersion) {
throw new Error(`Package '${packageName}' not found in lock file.`);
throw new Error(`Package '${packageName}' not found in lock file. Have you performed "velocitas init"?`);
}
return packageVersion;
}
Expand Down
5 changes: 4 additions & 1 deletion test/helpers/simpleGit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
import { CliFileSystem } from '../../src/utils/fs-bridge';
import { corePackageManifestMock, runtimePackageManifestMock, setupPackageManifestMock } from '../utils/mockConfig';

export const simpleGitInstanceMock = (mockedNewVersionTag?: string, checkRepo: boolean = true) => {
export const simpleGitInstanceMock = (mockedNewVersionTag?: string, checkRepo: boolean = true, checkRepo2: boolean = true) => {
return {
clone: async (repoPath: string, localPath: string, options?: any) => {
await CliFileSystem.promisesMkdir(localPath);
Expand All @@ -30,6 +30,9 @@ export const simpleGitInstanceMock = (mockedNewVersionTag?: string, checkRepo: b
}
},
checkIsRepo: () => {
let result = checkRepo;
// By default let second attempt succeed
checkRepo = checkRepo2;
return checkRepo;
},
fetch: () => {},
Expand Down
2 changes: 1 addition & 1 deletion test/unit/projectConfigIO.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ describe('projectConfigIO - module', () => {
it('should handle errors when parsing .velocitas.json file', () => {
const readFileStub = sinon.stub(CliFileSystem, 'readFileSync').throws();
const projectConfigFileReader = () => ProjectConfigIO.read('', configFilePath, true);
expect(projectConfigFileReader).to.throw(`Unable to read ${configFilePath}: unknown format!`);
expect(projectConfigFileReader).to.throw(`Unable to successfully read and interpret ${configFilePath}`);
readFileStub.restore();
});

Expand Down

0 comments on commit e5ed7aa

Please sign in to comment.