identity: refactor error hierarchy and error handling (#478)
Root motivation here was that a bunch of remote errors were trickling up
as full errors when doing identity resolution (via DID), while in
reality they should result in "invalid.handle".
I didn't want to just force everything in to ErrHandleNotFound, so I
created some new error types (and renamed a couple existing types), and
ensured that we were using errors.Is() for matching. This way downstream
code can distinguish between "not found" and "error during resolution"
when calling the lower-level methods, if they care (eg, a debugging tool
or interface would care). Also wrapped the errors instead of just
returning, so additional context couple be tacked on the message.
There are still some situations where the root cause might be a local
error (like local wifi) as opposed to a remote error (server is broken),
and we can't distinguish those, at least for now.
Note: I checked and recent versions of golang does explicitly allow
multiple `%w` in a single `fmt.Errorf()`