Whose Fault? Programming Error Responsibility Determination
In a traffic accident, it's highly unlikely an accident involves one person (e.g., a car hit a tree).
The car B in the back hits the car A in front. Whose fault? They went to the traffic court. The judge says the B car should watch out for the A car, and the A car should watch out for the B car. So they're both at fault, and each of them take 50% of the responsibility. Is this judge helpful? Is this judge "fair"? Is this law "right", in the sense that what if every traffic court judge is like this? This is not a traffic school blog, so I'll leave these common sense questions to yourself to think about. I'll just make one point, even if A sees B coming, what if A is blocked by another car in front of A? There is very limited things A can do, even if A watches out for B; on the other hand, B can do a lot if B watches out for A.
The world would go into a traffic chaos, if the judge is such a mess, or just try to be nice to both parties. That's why in real world traffic we have strict rules to clearly determine whose responsibility.
However, in the programming world, the situation is highly similar, but it seems to lack such a clearly distinction. In a traffic accident, it's highly unlikely an accident involves one person (e.g., a car hit a tree). In a programming accident, it's highly unlikely an accident involves one person who wrote all the code; even if one person who wrote all the code, it's highly unlikely it involves only one class.
When this class A calls that class B, and an error happens, whose fault? Let me define the situation rigorously.
Some class A calls some method of B (or equivalently) while passing some parameter C, such that the error is neither caused by A or B or C alone.
- A argues it's B's fault because B's method didn't handle A's call with parameter C.
- B argues it's A's fault because A passed in a parameter C that B didn't expect.
- C argues its innocence because A did the calling and B did the handling.
---
So? Whose fault?
- A's fault? A shouldn't pass in unhandlable parameter.
- B's fault? B should check if C meets B's requirement.
- interface's fault? The interface shouldn't allow the wrong C to go through the interface in the first place.
It's too much to explain why, but I'll just state my law here, in fact it's highly similar to a car hit another car in the back.
If the problem can be eliminated at the interface level, it's always 100% the interface's fault. Otherwise (maybe language restriction, too much speed sacrifice, etc), it's mainly A's fault.
B is always at minimum fault just like the car in front is not responsible for the car in the back. Let me show several examples.
class A
{
C c = null;
void Main()
{
X x =B.Function(c); // it's hard to rule out null at interface level
// why A forget to init C? what can B possibly do even if B checks for null
}
}
class A
{
double a = 2;
double b = 0;
void Main()
{
double c = Math.Divide(a,b); //it's hard to rule out 0 at interface level
// Why A divide by 0? What can Math.Divide do even if it checks for 0?
}
}
class A
{
double[] v1 = {1,2,3};
double[] v2 = {1,2,3,4};
void Main()
{
double[] v3 = Math.VectorAdd(v1,v2); //error, vector dimension don't match.
//should not use general interface double[] for vector. It should have specific interface such as Vector2 Vector3 Vector4, etc.
}
}