There is a serious problem with your implementation that should be pointed out: you put the Message call into a pattern test. This means that Message[] may get evaluated even if the corresponding definition of f[] isn't.
Suppose that you add the following additional definition to f[]:
f[x_] /; x < 0 := x^3
In this case f[-0.1] will still issue the message.
The correct way to do it is to put Message[] in the body of the function, so it only gets evaluated when the corresponding pattern does match:
f[x_Integer] := x^2f[___] := (Message[f:badarg]; Null)
The Null after Message is not really necessary as Message itself returns Null, but this pattern shows how to control the value being returned.