Skip to content

Commit

Permalink
Add additional validation error types
Browse files Browse the repository at this point in the history
All invalid changelog cases are now described by the
`InvalidChangelogError` error type, which has sub-classes to describe
each possible scenario. This allows distinguishing invalid changelog
errors from all other unexpected errors.

The CLI has been updated to take advantage of this; we now print a
simpler error message if the changelog is invalid, rather than a stack
trace.
  • Loading branch information
Gudahtt committed Apr 21, 2021
1 parent 57f1a08 commit 8b592ed
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 7 deletions.
6 changes: 5 additions & 1 deletion src/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ const { hideBin } = require('yargs/helpers');
const { updateChangelog } = require('./updateChangelog');
const { generateDiff } = require('./generateDiff');
const {
validateChangelog,
ChangelogFormattingError,
InvalidChangelogError,
validateChangelog,
} = require('./validateChangelog');
const { unreleased } = require('./constants');

Expand Down Expand Up @@ -79,6 +80,9 @@ async function validate({
const diff = generateDiff(validChangelog, invalidChangelog);
console.error(`Changelog not well-formatted.\nDiff:\n${diff}`);
process.exit(1);
} else if (error instanceof InvalidChangelogError) {
console.error(`Changelog is invalid: ${error.message}`);
process.exit(1);
}
throw error;
}
Expand Down
49 changes: 43 additions & 6 deletions src/validateChangelog.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,36 @@ const { parseChangelog } = require('./parseChangelog');
* @typedef {import('./constants.js').Version} Version
*/

/**
* Indicates that the changelog is invalid.
*/
class InvalidChangelogError extends Error {}

/**
* Indicates that unreleased changes are still present in the changelog.
*/
class UnreleasedChangesError extends InvalidChangelogError {
constructor() {
super('Unreleased changes present in the changelog');
}
}

/**
* Indicates that the release header for the current version is missing.
*/
class MissingCurrentVersionError extends InvalidChangelogError {
/**
* @param {Version} currentVersion - The current version
*/
constructor(currentVersion) {
super(`Current version missing from changelog: '${currentVersion}'`);
}
}

/**
* Represents a formatting error in a changelog.
*/
class ChangelogFormattingError extends Error {
class ChangelogFormattingError extends InvalidChangelogError {
/**
* @param {Object} options
* @param {string} options.validChangelog - The string contents of the well-
Expand Down Expand Up @@ -36,6 +62,13 @@ class ChangelogFormattingError extends Error {
* command will also ensure the current version is represented in the
* changelog with a release header, and that there are no unreleased changes
* present.
* @throws {InvalidChangelogError} Will throw if the changelog is invalid
* @throws {MissingCurrentVersionError} Will throw if `isReleaseCandidate` is
* `true` and the changelog is missing the release header for the current
* version.
* @throws {UnreleasedChangesError} Will throw if `isReleaseCandidate` is
* `true` and the changelog contains unreleased changes.
* @throws {ChangelogFormattingError} Will throw if there is a formatting error.
*/
function validateChangelog({
changelogContent,
Expand All @@ -52,14 +85,12 @@ function validateChangelog({
.getReleases()
.find((release) => release.version === currentVersion)
) {
throw new Error(
`Current version missing from changelog: '${currentVersion}'`,
);
throw new MissingCurrentVersionError(currentVersion);
}

const hasUnreleasedChanges = changelog.getUnreleasedChanges().length !== 0;
if (isReleaseCandidate && hasUnreleasedChanges) {
throw new Error('Unreleased changes present in the changelog');
throw new UnreleasedChangesError();
}

const validChangelog = changelog.toString();
Expand All @@ -71,4 +102,10 @@ function validateChangelog({
}
}

module.exports = { validateChangelog, ChangelogFormattingError };
module.exports = {
ChangelogFormattingError,
InvalidChangelogError,
MissingCurrentVersionError,
UnreleasedChangesError,
validateChangelog,
};

0 comments on commit 8b592ed

Please sign in to comment.