﻿id	summary	reporter	owner	description	type	status	priority	milestone	component	version	resolution	keywords	cc
13632	Introduce error logging mechanism	Piotrek Koszuliński	Szymon Kupś	"== The problem ==

Currently, if we want to log some error or warning we do this:

{{{
// jshint ignore:start
else { // %REMOVE_LINE%
	window.console && console.log( '[CKEDITOR.dom.selection.reset] Wrong selection instance resets fake selection.' ); // %REMOVE_LINE%
} // %REMOVE_LINE%
// jshint ignore:end
}}}

Or sometimes this:

{{{
if ( !editor.config.mathJaxLib && ( window.console && window.console.log ) ) {
	window.console.log( 'Error: config.mathJaxLib property is not set. For more information visit: ', docsUrl );
}
}}}

Or even this (async errors to avoid breaking the app by non-critical problems):

{{{
CKEDITOR.tools.setTimeout( function( name, pluginName ) {
	throw new Error( 'Plugin ""' + name.replace( ',', '' ) + '"" cannot be removed from the plugins list, because it\'s required by ""' + pluginName + '"" plugin.' );
}, 0, null, [ name, pluginName ] );
}}}

There are couple of issues with code like this:

* It's ugly and long. Messages (if not removed during building) are kept in the production ready code. So to avoid bloating it, we log very infrequently. This may need to change due to #11502.
* We do not have a fast option to turn this into code that throws to improve testability. The special case here and especially problematic is asynchronous code in which even if we throw an error, there's no way to catch it (OK, there's window.onerror, but that doesn't mute it AFAIK).
* There's no way to mute all console logs and errors if application requires it (see http://dev.ckeditor.com/ticket/11502#comment:16). There's no way to pipe them to some other output (e.g. a mechanism which sends them to the server).

== Solution ==

I would like to propose introducing two new methods:

{{{
CKEDITOR.error( errorCode [, additionalData... ] );
CKEDITOR.warn( errorCode [, additionalData... ] );
}}}

And complementary boolean flag and an event:

{{{
CKEDITOR.verbosity = CKEDITOR.VERBOSITY_(ERROR/LOG/NONE) {Number}
CKEDITOR#log
}}}

**What is errorCode**? It's not any more a full message. In order to not keep the full strings inside our code base, we will export them to a guide in docs. Error could would be built from location of a source file and some id:

* 'range-startcontainer'
* 'mathjax-lib'
* 'editor-removeplugins'
* 'selection-fake-reset'

So a class/plugin/module + a message identifier. Then, CKEDITOR.error/warn will log also a link to a guide where all errors are explained. A bit less user friendly, but especially with growing number of messages it will allow us to drop few KB and also improve the messages as they will be able to be longer.

I know that it's controversial because error codes are less useful, but I don't see a much choice for CKEditor 4. To keep long error messages in the code base, so in development version of the editor errors are fully meaningful we would need to:

* Agree that we bloat the code with them and keep them also in the production code.
* Implement a new feature in the builder which would look for CKEDITOR.warn/error and replace them with shorter calls (hashes of the messages?) as well as produce a documentation for these hashes. **Because we would need a guide for them anyway.**

The second solution sounds great for CKEditor 5, but not for CKEditor 4. Therefore I proposed this a little bit controversial change.

Behaviour:

1. CKEDITOR.error()
  * If `CKEDITOR.verbosity == CKEDITOR.VERBOSITY_ERROR`, throws a real error with all the details.
  * If not, then it fires CKEDITOR#log with data.type = error and all the details.
2. CKEDITOR.warn()
  * Fires CKEDITOR#log with data.type = warn and all the details.
3. CKEDITOR#log has a default (low prior) listener which:
  * If `CKEDITOR.verbosity == CKEDITOR.VERBOSITY_NONE`, then do nothing.
  * If type == error, then tries to use `console.error()` (downgrades to `console.log()` if the former does not exist)
  * If type == warn tries to use `console.warn()` (downgrades to `console.log()` if the former does not exist).
  * In both cases, it logs all the details plus a link to documentation (error codes)."	New Feature	closed	Normal	CKEditor 4.5.4	General		fixed		
