diff --git a/core/block.js b/core/block.js index ff5907e43..c8eda7d08 100644 --- a/core/block.js +++ b/core/block.js @@ -1107,7 +1107,7 @@ Blockly.Block.prototype.interpolate_ = function(message, args, lastDummyAlign) { } } goog.asserts.assert(indexCount == args.length, - 'Message does not reference all %s arg(s).', args.length); + 'block "%s": Message does not reference all %s arg(s).', this.type, args.length); // Add last dummy input if needed. if (elements.length && (typeof elements[elements.length - 1] == 'string' || goog.string.startsWith(elements[elements.length - 1]['type'], @@ -1449,3 +1449,20 @@ Blockly.Block.prototype.allInputsFilled = function(opt_shadowBlocksAreFilled) { return true; }; + +/** + * This method returns a string describing this Block in developer terms (type + * name and ID; English only). + * + * Intended to on be used in console logs and errors. If you need a string that + * uses the user's native language (including block text, field values, and + * child blocks), use [toString()]{@link Blockly.Block#toString}. + * @return {string} The description. + */ +Blockly.Block.prototype.toDevString = function() { + var msg = this.type ? '"' + this.type + '" block' : 'Block'; + if (this.id) { + msg += ' (id="' + this.id + '")'; + } + return msg; +}; diff --git a/core/blockly.js b/core/blockly.js index a3eeb68df..558c72014 100644 --- a/core/blockly.js +++ b/core/blockly.js @@ -405,9 +405,15 @@ Blockly.jsonInitFactory_ = function(jsonDef) { */ Blockly.defineBlocksWithJsonArray = function(jsonArray) { for (var i = 0, elem; elem = jsonArray[i]; i++) { - Blockly.Blocks[elem.type] = { - init: Blockly.jsonInitFactory_(elem) - }; + var typename = elem.type; + if (typename == null || typename === '') { + console.warn('Block definition #' + i + + ' in JSON array is missing a type attribute. Skipping.'); + } else { + Blockly.Blocks[typename] = { + init: Blockly.jsonInitFactory_(elem) + }; + } } }; diff --git a/core/connection.js b/core/connection.js index 88d6878e6..c68cd704c 100644 --- a/core/connection.js +++ b/core/connection.js @@ -330,7 +330,9 @@ Blockly.Connection.prototype.checkConnection_ = function(target) { case Blockly.Connection.REASON_TARGET_NULL: throw 'Target connection is null.'; case Blockly.Connection.REASON_CHECKS_FAILED: - throw 'Connection checks failed.'; + var msg = 'Connection checks failed. '; + msg += this + ' expected ' + this.check_ + ', found ' + target.check_; + throw msg; case Blockly.Connection.REASON_SHADOW_PARENT: throw 'Connecting non-shadow to shadow block.'; default: @@ -619,3 +621,33 @@ Blockly.Connection.prototype.setShadowDom = function(shadow) { Blockly.Connection.prototype.getShadowDom = function() { return this.shadowDom_; }; + +/** + * This method returns a string describing this Connection in developer terms + * (English only). Intended to on be used in console logs and errors. + * @return {string} The description. + */ +Blockly.Connection.prototype.toString = function() { + var msg; + var block = this.sourceBlock_; + if (!block) { + return 'Orphan Connection'; + } else if (block.outputConnection == this) { + msg = 'Output Connection of '; + } else if (block.previousConnection == this) { + msg = 'Previous Connection of '; + } else if (block.nextConnection == this) { + msg = 'Next Connection of '; + } else { + var parentInput = goog.array.find(block.inputList, function(input) { + return input.connection == this; + }, this); + if (parentInput) { + msg = 'Input "' + parentInput.name + '" connection on '; + } else { + console.warn('Connection not actually connected to sourceBlock_'); + return 'Orphan Connection'; + } + } + return msg + block.toDevString(); +};