Defensive distance

Number of input data checks depends on the distance from the caller.

When discussing defensive coding the same question always comes up: how much defensive coding is enough? The answer is very simple: the amount of defense is directly proportional to the distance from the code you are using.

immediate proximity

If the entity you are using is right there, you probably do not have to do any defense, unless you foresee a code refactoring and plan for it

1
2
3
4
function add(a, b) { return a + b; }
var a = 2,
b = 3;
var sum = add(a, b);

All 3 entities used to compute the sum (a, b, add) are very close together, thus I am not doing any defensive coding.

Medium distance

If the entities are within your sphere of control (your code, a well tested 3rd party library you bring as a dependency), you should do some sanity check. For example if we need angular library for our widget, we might check for it:

1
2
3
4
if (typeof angular === 'undefined') {
throw new Error('Widget Foo needs angularjs');
}
angular.module('Foo')...

Long distance

Any entity you have not control over requires strong defense against: things like user input, data from the server, 3rd party widget.

1
2
3
4
5
6
7
8
if (typeof angular === 'undefined')
throw new Error('Widget Foo needs angularjs');
}
if (angular.version.major < 1 &&
angular.version.minor < 12) {
throw new Error('Widget Foor requires angular >= 1.12');
}
angular.module('Foo')...

Going from data to the user interface leaps giant distance too. For example before showing something to the user, let us validate it

1
2
3
4
5
getUser().then(function onLoadedUserInfo(response) {
lazyAss(check.unemptyString(response.data.name),
'could not fetch user, does not have name', response);
popupModal('User ' + response.data.name + ' loaded');
});

In this code I am using a library of lazy assertions bahmutov/lazy-ass and library of predicates check-types.js.