diff --git a/packages/server/lib/modes/record.js b/packages/server/lib/modes/record.js index 9442fdf938..5594568bed 100644 --- a/packages/server/lib/modes/record.js +++ b/packages/server/lib/modes/record.js @@ -397,13 +397,19 @@ const createRun = Promise.method((options = {}) => { } }) }).catch((err) => { - debug('failed creating run %o', { + debug('failed creating run with status %d %o', err.statusCode, { stack: err.stack, }) switch (err.statusCode) { case 401: recordKey = keys.hide(recordKey) + if (!recordKey) { + // make sure the key is defined, otherwise the error + // printing logic substitutes the default value {} + // leading to "[object Object]" :) + recordKey = 'undefined' + } return errors.throw('DASHBOARD_RECORD_KEY_NOT_VALID', recordKey, projectId) case 402: { diff --git a/packages/server/lib/util/args.js b/packages/server/lib/util/args.js index 54dfdbcc27..ef0805cd64 100644 --- a/packages/server/lib/util/args.js +++ b/packages/server/lib/util/args.js @@ -238,6 +238,12 @@ module.exports = { project = undefined } + // if non-string key has been passed, set it to undefined + // https://github.com/cypress-io/cypress/issues/14571 + if (typeof options.key !== 'string') { + delete options.key + } + if (spec) { const resolvePath = (p) => { return path.resolve(options.cwd, p) diff --git a/packages/server/lib/util/keys.js b/packages/server/lib/util/keys.js index c7dfd626b7..abdeb243b1 100644 --- a/packages/server/lib/util/keys.js +++ b/packages/server/lib/util/keys.js @@ -3,6 +3,12 @@ const hide = (token) => { return } + if (typeof token !== 'string') { + // maybe somehow we passes key=true? + // https://github.com/cypress-io/cypress/issues/14571 + return + } + return [ token.slice(0, 5), token.slice(-5), diff --git a/packages/server/test/unit/args_spec.js b/packages/server/test/unit/args_spec.js index d904fad870..0b5b449fb4 100644 --- a/packages/server/test/unit/args_spec.js +++ b/packages/server/test/unit/args_spec.js @@ -365,7 +365,7 @@ describe('lib/util/args', () => { this.obj = { config: { foo: 'bar' }, project: 'foo/bar' } }) - it('rejects values which have an cooresponding underscore\'d key', function () { + it('rejects values which have an corresponding underscore\'d key', function () { expect(argsUtil.toArray(this.obj)).to.deep.eq([ `--config=${JSON.stringify({ foo: 'bar' })}`, '--project=foo/bar', diff --git a/packages/server/test/unit/modes/record_spec.js b/packages/server/test/unit/modes/record_spec.js index f937f43eb1..9b0456592a 100644 --- a/packages/server/test/unit/modes/record_spec.js +++ b/packages/server/test/unit/modes/record_spec.js @@ -5,6 +5,7 @@ const debug = require('debug')('test') const commitInfo = require('@cypress/commit-info') const mockedEnv = require('mocked-env') +const errors = require(`${root}../lib/errors`) const api = require(`${root}../lib/api`) const logger = require(`${root}../lib/logger`) const recordMode = require(`${root}../lib/modes/record`) @@ -492,6 +493,22 @@ describe('lib/modes/record', () => { expect(api.retryWithBackoff).to.be.calledOnce }) }) + + // https://github.com/cypress-io/cypress/issues/14571 + it('handles non-string key', async () => { + const apiError = new Error('Invalid Record Key') + + apiError.statusCode = 401 + + sinon.stub(api, 'retryWithBackoff').rejects(apiError) + sinon.spy(errors, 'throw') + await expect(recordMode.createRun({ + git: {}, + recordKey: true, // instead of a string + })).to.be.rejected + + expect(errors.throw).to.have.been.calledWith('DASHBOARD_RECORD_KEY_NOT_VALID', 'undefined') + }) }) context('.updateInstance', () => { diff --git a/packages/server/test/unit/util/keys_spec.ts b/packages/server/test/unit/util/keys_spec.ts new file mode 100644 index 0000000000..7851be19b9 --- /dev/null +++ b/packages/server/test/unit/util/keys_spec.ts @@ -0,0 +1,20 @@ +import { hide } from '../../../lib/util/keys' +import { expect } from 'chai' + +describe('util/keys', () => { + it('removes middle part of the string', () => { + const hidden = hide('12345-xxxx-abcde') + + expect(hidden).to.equal('12345...abcde') + }) + + it('returns undefined for missing key', () => { + expect(hide()).to.be.undefined + }) + + // https://github.com/cypress-io/cypress/issues/14571 + it('returns undefined for non-string argument', () => { + expect(hide(true)).to.be.undefined + expect(hide(1234)).to.be.undefined + }) +})