Skip to content

Commit

Permalink
Improve error message for missing apiKey and apiSecret
Browse files Browse the repository at this point in the history
I was debugging an error recently where I saw the following logged:

> No `apiKey` or `apiSecret` found in config. Falling back to
> pull-request authentication.

I believe in this particular case that only one of these was missing and
I thought it might be nice if this error message was a little more
specifically helpful.
  • Loading branch information
lencioni committed Jul 26, 2024
1 parent f462b79 commit 546da3d
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 10 deletions.
22 changes: 16 additions & 6 deletions src/loadUserConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,37 +60,47 @@ export default async function loadUserConfig(pathToConfigFile, env = process.env

const config = await load(pathToConfigFile);
if (!config.apiKey || !config.apiSecret) {
const missing = [
!config.apiKey ? 'apiKey' : null,
!config.apiSecret ? 'apiSecret' : null,
]
.filter(Boolean)
.map((key) => `\`${key}\``)
.join(' and ');

const prUrl = CHANGE_URL || resolvePRLink(env);
if (!prUrl) {
throw new Error(
'You need an `apiKey` and `apiSecret` in your config. ' +
'To obtain one, go to https://happo.io/settings',
`Missing ${missing} in your Happo config. Reference yours at https://happo.io/settings`,
);
}

try {
// Reassign api tokens to temporary ones provided for the PR
// Reassign API tokens to temporary ones provided for the PR
new Logger().info(
'No `apiKey` or `apiSecret` found in config. Falling back to pull-request authentication.',
`Missing ${missing} in Happo config. Falling back to pull-request authentication.`,
);
config.apiKey = prUrl;
config.apiSecret = await getPullRequestSecret(config, prUrl);
} catch (e) {
throw new WrappedError('Failed to obtain temporary pull-request token', e);
}
}

if (!config.targets || Object.keys(config.targets).length === 0) {
throw new Error(
'You need at least one target defined under `targets`. ' +
'See https://github.com/happo/happo.io#targets for more info.',
'You need at least one target defined under `targets` in your Happo config. See https://github.com/happo/happo.io#targets for more info.',
);
}

const defaultKeys = Object.keys(defaultConfig);
const usedKeys = Object.keys(config);
usedKeys.forEach((key) => {
if (!defaultKeys.includes(key)) {
new Logger().warn(`Unknown config key used in .happo.js: "${key}"`);
}
});

config.publicFolders.push(config.tmpdir);
config.plugins.forEach(({ publicFolders }) => {
if (publicFolders) {
Expand Down
24 changes: 20 additions & 4 deletions test/loadUserConfig-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,25 @@ beforeEach(() => {
}));
});

it('yells if api tokens are missing', async () => {
it('yells if both API tokens are missing', async () => {
requireRelative.mockImplementation(() => ({}));
await expect(loadUserConfig('bogus', {})).rejects.toThrow(/You need an `apiKey`/);
await expect(loadUserConfig('bogus', {})).rejects.toThrow(/Missing `apiKey` and `apiSecret` in your Happo config/);
});

it('yells if apiKey is missing', async () => {
requireRelative.mockImplementation(() => ({
apiSecret: '2',
targets: {},
}));
await expect(loadUserConfig('bogus', {})).rejects.toThrow(/Missing `apiKey` in your Happo config/);
});

it('yells if apiSecret is missing', async () => {
requireRelative.mockImplementation(() => ({
apiKey: '1',
targets: {},
}));
await expect(loadUserConfig('bogus', {})).rejects.toThrow(/Missing `apiSecret` in your Happo config/);
});

it('yells if targets are missing', async () => {
Expand Down Expand Up @@ -101,7 +117,7 @@ describe('when CHANGE_URL is defined', () => {
it('adds a log', async () => {
await loadUserConfig('bogus', { CHANGE_URL: 'foo.bar' });
expect(info.mock.calls[0][0]).toEqual(
'No `apiKey` or `apiSecret` found in config. Falling back to pull-request authentication.',
'Missing `apiKey` and `apiSecret` in Happo config. Falling back to pull-request authentication.',
);
});

Expand Down Expand Up @@ -146,7 +162,7 @@ describe('when GITHUB_EVENT_PATH is defined', () => {
loadUserConfig('bogus', {
GITHUB_EVENT_PATH: path.resolve(__dirname, 'github_push_event.json'),
}),
).rejects.toThrow(/You need an.*apiSecret/);
).rejects.toThrow(/Missing `apiKey` and `apiSecret`/);
});
});
});
Expand Down

0 comments on commit 546da3d

Please sign in to comment.