ckeditorerror.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /**
  2. * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  4. */
  5. /**
  6. * @module utils/ckeditorerror
  7. */
  8. /**
  9. * URL to the documentation with error codes.
  10. */
  11. export const DOCUMENTATION_URL =
  12. 'https://ckeditor.com/docs/ckeditor5/latest/framework/guides/support/error-codes.html';
  13. /**
  14. * The CKEditor error class.
  15. *
  16. * You should throw `CKEditorError` when:
  17. *
  18. * * An unexpected situation occurred and the editor (most probably) will not work properly. Such exception will be handled
  19. * by the {@link module:watchdog/watchdog~Watchdog watchdog} (if it is integrated),
  20. * * If the editor is incorrectly integrated or the editor API is used in the wrong way. This way you will give
  21. * feedback to the developer as soon as possible. Keep in mind that for common integration issues which should not
  22. * stop editor initialization (like missing upload adapter, wrong name of a toolbar component) we use `console.warn()` with
  23. * {@link module:utils/ckeditorerror~attachLinkToDocumentation `attachLinkToDocumentation()`}
  24. * to improve developers experience and let them see the working editor as soon as possible.
  25. *
  26. * /**
  27. * * Error thrown when a plugin cannot be loaded due to JavaScript errors, lack of plugins with a given name, etc.
  28. * *
  29. * * @error plugin-load
  30. * * @param pluginName The name of the plugin that could not be loaded.
  31. * * @param moduleName The name of the module which tried to load this plugin.
  32. * * /
  33. * throw new CKEditorError( 'plugin-load: It was not possible to load the "{$pluginName}" plugin in module "{$moduleName}', {
  34. * pluginName: 'foo',
  35. * moduleName: 'bar'
  36. * } );
  37. *
  38. * @extends Error
  39. */
  40. export default class CKEditorError extends Error {
  41. /**
  42. * Creates an instance of the CKEditorError class.
  43. *
  44. * @param {String} message The error message in an `error-name: Error message.` format.
  45. * During the minification process the "Error message" part will be removed to limit the code size
  46. * and a link to this error documentation will be added to the `message`.
  47. * @param {Object|null} context A context of the error by which the {@link module:watchdog/watchdog~Watchdog watchdog}
  48. * is able to determine which editor crashed. It should be an editor instance or a property connected to it. It can be also
  49. * a `null` value if the editor should not be restarted in case of the error (e.g. during the editor initialization).
  50. * The error context should be checked using the `areConnectedThroughProperties( editor, context )` utility
  51. * to check if the object works as the context.
  52. * @param {Object} [data] Additional data describing the error. A stringified version of this object
  53. * will be appended to the error message, so the data are quickly visible in the console. The original
  54. * data object will also be later available under the {@link #data} property.
  55. */
  56. constructor( message, context, data ) {
  57. message = attachLinkToDocumentation( message );
  58. if ( data ) {
  59. message += ' ' + JSON.stringify( data );
  60. }
  61. super( message );
  62. /**
  63. * @type {String}
  64. */
  65. this.name = 'CKEditorError';
  66. /**
  67. * A context of the error by which the Watchdog is able to determine which editor crashed.
  68. *
  69. * @type {Object|null}
  70. */
  71. this.context = context;
  72. /**
  73. * The additional error data passed to the constructor. Undefined if none was passed.
  74. *
  75. * @type {Object|undefined}
  76. */
  77. this.data = data;
  78. }
  79. /**
  80. * Checks if the error is of the `CKEditorError` type.
  81. */
  82. is( type ) {
  83. return type === 'CKEditorError';
  84. }
  85. /**
  86. * A utility that ensures the the thrown error is a {@link module:utils/ckeditorerror~CKEditorError} one.
  87. * It is uesful when combined with the {@link module:watchdog/watchdog~Watchdog} feature, which can restart the editor in case
  88. * of a {@link module:utils/ckeditorerror~CKEditorError} error.
  89. *
  90. * @param {Error} err An error.
  91. * @param {Object} context An object conected through properties with the editor instance. This context will be used
  92. * by the watchdog to verify which editor should be restarted.
  93. */
  94. static rethrowUnexpectedError( err, context ) {
  95. if ( err.is && err.is( 'CKEditorError' ) ) {
  96. throw err;
  97. }
  98. /**
  99. * An unexpected error occurred inside the CKEditor 5 codebase. The `error.data.originalError` property
  100. * shows the original error properties.
  101. *
  102. * This error is only useful when the editor is initialized using the {@link module:watchdog/watchdog~Watchdog} feature.
  103. * In case of such error (or any {@link module:utils/ckeditorerror~CKEditorError} error) the wathcdog should restart the editor.
  104. *
  105. * @error unexpected-error
  106. */
  107. throw new CKEditorError( 'unexpected-error', context, {
  108. originalError: {
  109. message: err.message,
  110. stack: err.stack,
  111. name: err.name
  112. }
  113. } );
  114. }
  115. }
  116. /**
  117. * Attaches the link to the documentation at the end of the error message. Use whenever you log a warning or error on the
  118. * console. It is also used by {@link module:utils/ckeditorerror~CKEditorError}.
  119. *
  120. * /**
  121. * * There was a problem processing the configuration of the toolbar. The item with the given
  122. * * name does not exist so it was omitted when rendering the toolbar.
  123. * *
  124. * * @error toolbarview-item-unavailable
  125. * * @param {String} name The name of the component.
  126. * * /
  127. * console.warn( attachLinkToDocumentation(
  128. * 'toolbarview-item-unavailable: The requested toolbar item is unavailable.' ), { name } );
  129. *
  130. * @param {String} message Message to be logged.
  131. * @returns {String}
  132. */
  133. export function attachLinkToDocumentation( message ) {
  134. const matchedErrorName = message.match( /^([^:]+):/ );
  135. if ( !matchedErrorName ) {
  136. return message;
  137. }
  138. return message + ` Read more: ${ DOCUMENTATION_URL }#error-${ matchedErrorName[ 1 ] }\n`;
  139. }