Building a try {} catch(err) {} block for javascript

568 views
Skip to first unread message

Siman007

unread,
Oct 21, 2013, 4:25:27 PM10/21/13
to blo...@googlegroups.com

Hi I'm a newbie to Blockly and I'm trying to extend the javascript support a try catch block

I'm completely stuck on how to generate/add the error var for the catch part of the block so I can display the error, dos anybody have any ideas?

Thank you so much :-)

So far I have the following try catch block working - but it doesn't generate a variable for the error so I can pass it to the print statement

Blockly.Blocks['control_trycatch'] = {
  // trycatch
  init: function() {
    this.setHelpUrl('http://somewhere/trycatch.html');
    this.setColour(120);
    this.appendStatementInput('TRY')
        .appendTitle('try');
    this.appendStatementInput('CATCH')
        .appendTitle('catch');
    this.setPreviousStatement(true);
    this.setNextStatement(true);
    this.setTooltip('Standard try { } carch (err) {..}');
  }
};


And the following for the javascript generator

Blockly.JavaScript['control_trycatch'] = function(block) {
  // try catch
  var tryblock = Blockly.JavaScript.statementToCode(block, 'TRY');
  var catchblock = Blockly.JavaScript.statementToCode(block, 'CATCH');
  var code = 'try {\n' + tryblock + '}\n';
  code += 'catch(err){\n' + catchblock + '}\n';
  return code + '\n';
};

 

Ellen Spertus

unread,
Oct 21, 2013, 4:33:36 PM10/21/13
to blo...@googlegroups.com
In the code generation, you'll need a call to  Blockly.JavaScript.variableDB_.getDistinctName to generate a unique name, rather than hardcoding "err", which may have been defined elsewhere by the user or in a nested try-catch block.

You could create a new variable "error" or "exception" and disallow its placement anywhere but in a try-catch block, just like the if-return block can only be placed in a procedure.




--
You received this message because you are subscribed to the Google Groups "Blockly" group.
To unsubscribe from this group and stop receiving emails from it, send an email to blockly+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Siman007

unread,
Oct 21, 2013, 5:37:38 PM10/21/13
to blo...@googlegroups.com
Thank you I have tried both;  for the error block I have copied the if-return block and modified it

How would I let the user set the var name of the error block so I could then reference it in blockly

So far my error block is....


Blockly.Blocks['control_try_error'] = {
  // Conditionally return value from a try catch.
  init: function() {
    this.setHelpUrl('http://c2.com/cgi/wiki?GuardClause');
    this.setColour(290);
       this.appendValueInput('VALUE')
        .appendTitle(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN);
    this.setInputsInline(true);
    this.setPreviousStatement(true);
    this.setNextStatement(true);
    this.setTooltip(Blockly.Msg.PROCEDURES_IFRETURN_TOOLTIP);
    this.hasReturnValue_ = true;
  },
  mutationToDom: function() {
    // Save whether this block has a return value.
    var container = document.createElement('mutation');
    container.setAttribute('value', Number(this.hasReturnValue_));
    return container;
  },
  domToMutation: function(xmlElement) {
    // Restore whether this block has a return value.
    var value = xmlElement.getAttribute('value');
    this.hasReturnValue_ = (value == 1);
    if (!this.hasReturnValue_) {
      this.removeInput('VALUE');
      this.appendDummyInput('VALUE')
        .appendTitle(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN);
    }
  },
  onchange: function() {
    if (!this.workspace) {
      // Block has been deleted.
      return;
    }
    var legal = false;
    // Is the block nested in a procedure?
    var block = this;
   block = block.getSurroundParent();
    if (block.type == 'sds_try' ) {
        this.removeInput('VALUE');
        this.appendValueInput('VALUE')
          .appendTitle("Error Value");
        this.hasReturnValue_ = true;
           
        this.setWarningText(null);
    } else {
      this.setWarningText("This block must be contained within a try catch");
    }
  }
};

Ellen Spertus

unread,
Oct 21, 2013, 5:43:29 PM10/21/13
to blo...@googlegroups.com
On Mon, Oct 21, 2013 at 2:37 PM, Siman007 <willc...@googlemail.com> wrote:
How would I let the user set the var name of the error block so I could then reference it in blockly

I wouldn't let them set the name.  I'd automatically generate it.

To avoid confusion, I'll contradict what I said before and suggest you hardcode a name.  While that will make it impossible to access enclosing exceptions, it will make things simpler.

You don't need any mutationToDom code.  You'll need a different variable than hasReturnValue_ since you don't want to allow if-return to work from control_try_error.  I meant doing something similar to what is done in if-return not using the same code.

Ellen 

Siman007

unread,
Oct 22, 2013, 5:59:45 AM10/22/13
to blo...@googlegroups.com
Ellen thank you, I have gone back to simply hard coding the Err message - in my case I can get away with passing the err to a standard handler so I have coded for that - but left the option to add additional functions to the catch if required.


So my code (if its of use to anybody else) is

Blockly.Blocks['controls_try'] = {
  // Try
  init: function() {
    this.setHelpUrl(Blockly.Msg.CONTROLS_REPEAT_HELPURL);

    this.setColour(120);
    this.appendStatementInput('TRY')
        .appendTitle('try');
    this.appendStatementInput('CATCH')
        .appendTitle('catch');
    this.setPreviousStatement(true);
    this.setNextStatement(true);
    this.setTooltip('Standard try { } carch (err) {..} you must provide an error handler to consume the error message');
  }
};


And for the javascript generator

Blockly.JavaScript['controls_try'] = function(block) {

  // try catch
  var tryblock = Blockly.JavaScript.statementToCode(block, 'TRY');
  var catchblock = Blockly.JavaScript.statementToCode(block, 'CATCH');
  var code = 'try {\n' + tryblock + '}\n';
  code += 'catch(err){\n errorHandler(err.message);\n' + catchblock + '\n}';
  return code + '\n';
};

All I need to do is remember to add an error handler as an additional function

Thanks again

Simon
Reply all
Reply to author
Forward
0 new messages