Author(s): Hayden Smith
The simplest way to deal with problems at run-time...
Just crash
import prompt from 'prompt-sync'; const promptFn = prompt(); function sqrt(x: number) { if (x < 0) { console.error('Error Input < 0'); process.exit(1); } return Math.pow(x, 0.5); } const input = promptFn('Please enter a number: '); console.log(sqrt(parseInt(input)));
5.4_just_crash.tsNot very clean though.
However, if we throw an exception 😵💫 we start to get into a new territory of programming.
import prompt from 'prompt-sync'; const promptFn = prompt(); function sqrt(x: number) { if (x < 0) { throw new Error('Error Input < 0'); } return Math.pow(x, 0.5); } const input = promptFn('Please enter a number: '); console.log(sqrt(parseInt(input)));
5.4_exception1.tsHowever, if we throw an exception 😵💫 we start to get into a new territory of programming.
import prompt from 'prompt-sync'; const promptFn = prompt(); function sqrt(x: number) { if (x < 0) { throw new Error('Error Input < 0'); } return Math.pow(x, 0.5); } const input = promptFn('Please enter a number: '); console.log(sqrt(parseInt(input)));
5.4_exception1.tsLet's take a step back...
An exception is an action that disrupts the normal flow of a program. This action is often representative of an error being thrown. Exceptions are ways that we can elegantly recover from errors.
Exceptions are a particular method of ensuring software safety. Different languages have different conventions for managing unexpected runtime events.
Javascript relies on Exceptions for the majority of error handling. Unlike C, which has no exceptions
This program is good in that it throws an exception, but we aren't handling it.
import prompt from 'prompt-sync'; const promptFn = prompt(); function sqrt(x: number) { if (x < 0) { throw new Error('Error Input < 0'); } return Math.pow(x, 0.5); } const input = promptFn('Please enter a number: '); console.log(sqrt(parseInt(input)));
5.4_exception1.tsThis program is good in that it throws an exception, but we aren't handling it.
import prompt from 'prompt-sync'; const promptFn = prompt(); function sqrt(x: number) { if (x < 0) { throw new Error('Error Input < 0'); } return Math.pow(x, 0.5); } try { const input = promptFn('Please enter a number: '); console.log(sqrt(parseInt(input))); } catch (err) { console.error(`Error when inputting! ${err}`); const input = promptFn('Please enter a number: '); console.log(sqrt(parseInt(input))); }
5.4_exception2.tsOr we could make this even more robust
import prompt from 'prompt-sync'; const promptFn = prompt(); function sqrt(x: number) { if (x < 0) { throw new Error('Error Input < 0'); } return Math.pow(x, 0.5); } let success = false; while (!success) { try { const input = promptFn('Please enter a number: '); console.log(sqrt(parseInt(input))); success = true; } catch (err) { console.error(`Error when inputting! ${err}`); } }
5.4_exception3.tsfunction sqrt(x: number) { if (x < 0) { throw new Error('Error Input < 0'); } return Math.pow(x, 0.5); } if (process.argv.length === 3) { try { console.log(sqrt(parseInt(process.argv[2]))); console.log('Never called if error!'); } catch (err) { console.error(`Error when inputting! ${err}`); } }
5.4_throw_catch.tsWe can use jest
s toThrowError
function to test if functions are appropriately throwing exceptions.
function sqrt(x: number) { if (x < 0) { throw new Error('Error Input < 0'); } return Math.pow(x, 0.5); } export { sqrt };
5.4_sqrt.tsimport { sqrt } from './5.2_sqrt'; describe('sqrt correctness', () => { test('deals with valid bases', () => { expect(sqrt(4)).toEqual(2); expect(sqrt(2)).toBeCloseTo(1.414213, 5); }); test('throws error on negatives', () => { // Note that these require a function, not result expect(() => sqrt(-2)).toThrow('Error: Input < 0'); expect(() => sqrt(-5)).toThrowError('Error: Input < 0'); }); });
5.4_catch.test.ts