Overview of the way that Fieldtypes and Inputfields interact with each other when it comes to validation.
Inputfields only come into play when there's interactivity, i.e. a form and a user inputting something. Input should be validated by Inputfields so that the data is valid enough to echo back to the user, or for something else to pull the value from it. Inputfields should always be validated server-side where appropriate, but can also optionally include client-side validation. Inputfields can be used separately from Fieldtypes (they are used throughout ProcessWire in all forms). If there is some kind of input validation that isn't specific to a page or fieldtype, then it should be done by the Inputfield. Meaning, most validation responsibility goes with the Inputfield and an Inputfield shouldn't assume there's going to be any more validation beyond it.
Inputfield sanitization/validation is done in $inputfield->processInput() or $inputfield->setAttribute('value', ...). The processInput() method is the first line of defense for values coming directly from a form. Whereas the setAttribute('value', ...) will see values sent from the form as well as values sent from the API to the $inputfield, like an $inputfield->attr('value', 'some value'), call. Where you put your sanitization/validation depends on what you are trying to account for.
You may see some Inputfields have a setAttributeValue() function. This is not part of the Inputfield interface. It's just a methodology I sometimes use to isolate setAttribute('value', ...) for more readable code.
Inputfields report errors by calling $this->error('error message'); The user will see that error message within the context of the field.
Fieldtypes come into play every time a value is populated to a page. This could be from the API, the core, modules, importers, Inputfields… really anything. They need to validate that the value sent to the page is consistent with the type of data the Fieldtype is responsible for (type validation). So if the Fieldtype only stores a string, then it needs to make sure it's a string. If you set something invalid to a $page, the Fieldtype needs to either convert it to be something valid or if it can't, throw it out. For the most part, they should do it as quickly and silently as possible, because they get such a high volume of traffic. Not to mention, Fieldtypes can't assume there's a user present to see anything.
Fieldtype sanitization/validation is performed by $fieldtype->sanitizeValue(). Every value set to a $page gets routed through that function, for the appropriate fieldtype. Whatever you do in there needs to be fast.