From a local user's point of view, the most important function of the full node is to tell them when funds are received and confirmed. For instance, if the local user is a merchant, this is what they need to know in determining when to ship goods to customers.
So from this perspective, the most important thing for a full node to do if it finds an invalid transaction or block is to ignore it. For an invalid transaction, it needs to not report the transaction to the user as received funds. For an invalid block, it needs to not report this as confirmation for the transactions in the block, nor as an additional confirmation for transactions confirmed in previous blocks.
A merchant considers an invalid transaction to be the same as no transaction at all. A user who paid with an invalid transaction effectively just hasn't paid, and will be ignored until they come up with real funds. An invalid block simply isn't a confirmation, and if we are waiting for some number of confirmations before shipping goods, then we just have to keep waiting.
Sure, the node can ban the other node that sent the offending data, or log an error, or whatever. This is a good idea as far as saving bandwidth for valid data, or giving the user some general info about the state of network, or aiding in debugging. But all this is secondary.