diff --git a/src/ckeditorerror.js b/src/ckeditorerror.js index 0fe14eb..55dcbe2 100644 --- a/src/ckeditorerror.js +++ b/src/ckeditorerror.js @@ -7,6 +7,11 @@ * @module utils/ckeditorerror */ +/** + * URL to the documentation with error codes. + */ +export const DOCUMENTATION_URL = 'https://ckeditor5.github.io/docs/nightly/ckeditor5/latest/framework/guides/error-codes.html'; + /** * The CKEditor error class. * @@ -31,6 +36,8 @@ export default class CKEditorError extends Error { * data object will also be later available under the {@link #data} property. */ constructor( message, data ) { + message = attachLinkToDocumentation( message ); + if ( data ) { message += ' ' + JSON.stringify( data ); } @@ -60,3 +67,19 @@ export default class CKEditorError extends Error { return error instanceof CKEditorError; } } + +/** + * Attaches link to the documentation at the end of the error message. + * + * @param {String} message Message to be logged. + * @returns {String} + */ +export function attachLinkToDocumentation( message ) { + const matchedErrorName = message.match( /^([^:]+):/ ); + + if ( !matchedErrorName ) { + return message; + } + + return message + ` Read more: ${ DOCUMENTATION_URL }#${ matchedErrorName[ 1 ] }.\n`; +} diff --git a/src/log.js b/src/log.js index 9355f3e..f3a339e 100644 --- a/src/log.js +++ b/src/log.js @@ -9,6 +9,8 @@ * @module utils/log */ +import { attachLinkToDocumentation } from './ckeditorerror'; + /** * The logging module. * @@ -53,7 +55,7 @@ const log = { * @param {Object} [data] Additional data describing the error. */ error( message, data ) { - console.error( message, data ); + console.error( attachLinkToDocumentation( message ), data ); }, /** @@ -67,7 +69,7 @@ const log = { * @param {Object} [data] Additional data describing the warning. */ warn( message, data ) { - console.warn( message, data ); + console.warn( attachLinkToDocumentation( message ), data ); } }; diff --git a/tests/ckeditorerror.js b/tests/ckeditorerror.js index 89e75ff..bcc633c 100644 --- a/tests/ckeditorerror.js +++ b/tests/ckeditorerror.js @@ -3,7 +3,7 @@ * For licensing, see LICENSE.md. */ -import CKEditorError from '../src/ckeditorerror'; +import { default as CKEditorError, DOCUMENTATION_URL } from '../src/ckeditorerror'; describe( 'CKEditorError', () => { it( 'inherits from Error', () => { @@ -52,6 +52,25 @@ describe( 'CKEditorError', () => { expect( error ).to.have.property( 'data', data ); } ); + it( 'contains a link which leads to the documentation', () => { + const error = new CKEditorError( 'model-schema-no-item: Specified item cannot be found.' ); + + const errorMessage = 'model-schema-no-item: Specified item cannot be found. ' + + `Read more: ${ DOCUMENTATION_URL }#model-schema-no-item.\n`; + + expect( error ).to.have.property( 'message', errorMessage ); + } ); + + it( 'link to documentation is added before the additional data message', () => { + const error = new CKEditorError( 'model-schema-no-item: Specified item cannot be found.', { foo: 1, bar: 2 } ); + + const errorMessage = 'model-schema-no-item: Specified item cannot be found. ' + + `Read more: ${ DOCUMENTATION_URL }#model-schema-no-item.\n ` + + '{"foo":1,"bar":2}'; + + expect( error ).to.have.property( 'message', errorMessage ); + } ); + describe( 'isCKEditorError', () => { it( 'checks if error is an instance of CKEditorError', () => { const ckeditorError = new CKEditorError( 'foo' ); diff --git a/tests/log.js b/tests/log.js index e8909a2..bf56bcd 100644 --- a/tests/log.js +++ b/tests/log.js @@ -6,6 +6,7 @@ /* globals console */ import log from '../src/log'; +import { DOCUMENTATION_URL } from '../src/ckeditorerror'; describe( 'log', () => { let spy; @@ -18,7 +19,7 @@ describe( 'log', () => { describe( 'warn()', () => { it( 'logs the message to the console using console.warn()', () => { - const spy = sinon.stub( console, 'warn' ); + spy = sinon.stub( console, 'warn' ); const data = { bar: 1 }; log.warn( 'foo', data ); @@ -30,11 +31,23 @@ describe( 'log', () => { sinon.assert.calledTwice( spy ); sinon.assert.calledWith( spy, 'bar' ); } ); + + it( 'contains a link which leads to the documentation', () => { + spy = sinon.stub( console, 'warn' ); + + log.warn( 'model-schema-no-item: Specified item cannot be found.' ); + + const logMessage = 'model-schema-no-item: Specified item cannot be found. ' + + `Read more: ${ DOCUMENTATION_URL }#model-schema-no-item.\n`; + + sinon.assert.calledOnce( spy ); + sinon.assert.calledWith( spy, logMessage ); + } ); } ); describe( 'error()', () => { it( 'logs the message to the console using console.error()', () => { - const spy = sinon.stub( console, 'error' ); + spy = sinon.stub( console, 'error' ); const data = { bar: 1 }; log.error( 'foo', data ); @@ -46,5 +59,17 @@ describe( 'log', () => { sinon.assert.calledTwice( spy ); sinon.assert.calledWith( spy, 'bar' ); } ); + + it( 'contains a link which leads to the documentation', () => { + spy = sinon.stub( console, 'error' ); + + log.error( 'model-schema-no-item: Specified item cannot be found.' ); + + const logMessage = 'model-schema-no-item: Specified item cannot be found. ' + + `Read more: ${ DOCUMENTATION_URL }#model-schema-no-item.\n`; + + sinon.assert.calledOnce( spy ); + sinon.assert.calledWith( spy, logMessage ); + } ); } ); } );