<!DOCTYPE html>
<html>
<head>
<title></title>
<style type="text/css">p.MsoNormal,p.MsoNoSpacing{margin:0}</style>
</head>
<body><div>Hi everyone,<br></div>
<div><br></div>
<div>I'm hoping this is the right medium to ask this but I would like to propose a language feature called try/catch/else.<br></div>
<div><br></div>
<div>Conditional try/catch seems to be all the rage right now but in many cases the problem it really wants to solve seems to be code like the following:<br></div>
<div><br></div>
<div><span class="font" style="font-family:menlo, consolas, monospace, sans-serif">try {</span><span class="font" style="font-family:menlo, consolas, monospace, sans-serif"></span><br></div>
<div><span class="font" style="font-family:menlo, consolas, monospace, sans-serif">  const suggestions = await fetchSuggestions();</span><span class="font" style="font-family:menlo, consolas, monospace, sans-serif"></span><br></div>
<div><span class="font" style="font-family:menlo, consolas, monospace, sans-serif">  showSuggestions(suggestions);</span><span class="font" style="font-family:menlo, consolas, monospace, sans-serif"></span><br></div>
<div><span class="font" style="font-family:menlo, consolas, monospace, sans-serif">} catch (e) {</span><span class="font" style="font-family:menlo, consolas, monospace, sans-serif"></span><br></div>
<div><span class="font" style="font-family:menlo, consolas, monospace, sans-serif">  alert('Failed to load suggestions');</span><span class="font" style="font-family:menlo, consolas, monospace, sans-serif"></span><br></div>
<div><span class="font" style="font-family:menlo, consolas, monospace, sans-serif">  // Oops, we also swallow errors from showSuggestions</span><span class="font" style="font-family:menlo, consolas, monospace, sans-serif"></span><br></div>
<div><span class="font" style="font-family:menlo, consolas, monospace, sans-serif">}</span><br></div>
<div><span class="font" style="font-family:menlo, consolas, monospace, sans-serif">// now do something else</span><br></div>
<div><br></div>
<div>Having a more fine-grained <span class="font" style="font-family:menlo, consolas, monospace, sans-serif">catch</span> wouldn't necessarily help here because both functions might throw the same kind of error but what we're really interested in is discerning the <i>source</i> of the error. So instead some people resort to something like this:<br></div>
<div><div><br></div>
</div>
<div><span class="font" style="font-family:menlo, consolas, monospace, sans-serif">let suggestions;</span><br></div>
<div><span class="font" style="font-family:menlo, consolas, monospace, sans-serif">try {</span><br></div>
<div><span class="font" style="font-family:menlo, consolas, monospace, sans-serif">  suggestions = await fetchSuggestions();</span><br></div>
<div><span class="font" style="font-family:menlo, consolas, monospace, sans-serif">} catch (e) {</span><br></div>
<div><span class="font" style="font-family:menlo, consolas, monospace, sans-serif">  alert('Failed to load suggestions');</span><br></div>
<div><span class="font" style="font-family:menlo, consolas, monospace, sans-serif">  return;</span><br></div>
<div><span class="font" style="font-family:menlo, consolas, monospace, sans-serif">}</span><br></div>
<div><div><span class="font" style="font-family:menlo, consolas, monospace, sans-serif">showSuggestions(suggestions);</span><br></div>
<div><span class="font" style="font-family:menlo, consolas, monospace, sans-serif">// now do something else - unless we failed to load</span><br></div>
<div><br></div>
</div>
<div>Note how we're forced to add a <span class="font" style="font-family:menlo, consolas, monospace, sans-serif">return</span> to explicitly abort the control flow. Unlike the change from const to let this isn't something an IDE would point out while refactoring, so this actually introduces potential for bugs. If we don't actually want to bail out completely this often leads to noisy status booleans (e.g. <span class="font" style="font-family:menlo, consolas, monospace, sans-serif">didNotThrow</span>) or error-prone checks (e.g. <span class="font" style="font-family:menlo, consolas, monospace, sans-serif">!suggestions</span> is a bug if the async function really didn't return anything).<br></div>
<div><br></div>
<div>I'm not sure about other languages but Python has a solution for this by adding an <span class="font" style="font-family:menlo, consolas, monospace, sans-serif">else</span> clause:<br></div>
<div><br></div>
<div><span class="font" style="font-family:menlo, consolas, monospace, sans-serif">let suggestions;</span><br></div>
<div><span class="font" style="font-family:menlo, consolas, monospace, sans-serif">try {</span><br></div>
<div><span class="font" style="font-family:menlo, consolas, monospace, sans-serif">  suggestions = await fetchSuggestions();</span><br></div>
<div><span class="font" style="font-family:menlo, consolas, monospace, sans-serif">} catch (e) {</span><br></div>
<div><span class="font" style="font-family:menlo, consolas, monospace, sans-serif">  alert('Failed to load suggestions');</span><br></div>
<div><span class="font" style="font-family:menlo, consolas, monospace, sans-serif">} else {</span><br></div>
<div><div><span class="font" style="font-family:menlo, consolas, monospace, sans-serif">  showSuggestions(suggestions);</span><br></div>
<div><span class="font" style="font-family:menlo, consolas, monospace, sans-serif">}</span><br></div>
<div><span class="font" style="font-family:menlo, consolas, monospace, sans-serif">// now do something else</span><br></div>
<div><div><br></div>
</div>
</div>
<div>The semantics are pretty straightforward: if the <span class="font" style="font-family:menlo, consolas, monospace, sans-serif">try</span> block did not throw, the <span class="font" style="font-family:menlo, consolas, monospace, sans-serif">else</span> block is executed next (before the <span class="font" style="font-family:menlo, consolas, monospace, sans-serif">finally</span> block if any). If the <span class="font" style="font-family:menlo, consolas, monospace, sans-serif">try</span> block does throw, the <span class="font" style="font-family:menlo, consolas, monospace, sans-serif">else</span> block is ignored (like a conditional <span class="font" style="font-family:menlo, consolas, monospace, sans-serif">catch</span> that doesn't match).<br></div>
<div><br></div>
<div>I realise there is some ambiguity in using the <span class="font" style="font-family:menlo, consolas, monospace, sans-serif">else</span> keyword for this (though I can't think of a meaningful opposite of "catch" either). There is also some overlap with conditional try/catch but I think this language feature is useful even if conditional try/catch exists.<br></div>
<div><br></div>
<div><br></div>
<div>Cheers,<br></div>
<div><br></div>
<div>Alan Plum<br></div>
</body>
</html>