Any interaction with a file descriptor can already fail (eg. pretty much anything can potentially give you EIO).
Using fuser() in that way is racy, and how is kill() any better than returning a possibly-ignored error anyway? You can't do program-specific actions because the point is to enforce "You did have permission to open that, but now you don't and you aren't allowed to keep using it".
We may be talking about different things but why would you need to close an fd "externally" when (at least for pipes and sockets) there is someone on the other side who can just close it regularly?
revoke() would be useful for things like device nodes (and even regular files) - consider "you can open the sound device while you are logged in locally, but you can't keep using it after you've logged off".
Using fuser() in that way is racy, and how is kill() any better than returning a possibly-ignored error anyway? You can't do program-specific actions because the point is to enforce "You did have permission to open that, but now you don't and you aren't allowed to keep using it".