serokell / coffer

Multi-backend password store with multiple frontends
4 stars 2 forks source link

[#24] Better error handling #60

Closed DK318 closed 2 years ago

DK318 commented 2 years ago

Description

Problem

In Backend.Vault.Kv error handling is very bad. We lose a lot of info about thrown exceptions.

Solution

Added more CofferError constructors (e.g. RequestFailed and DecodeFailed) which stores all necessary information and wrote Buildable instance for it.

Related issue(s)

MagicRB commented 2 years ago

The issue with a concrete error type is that a Vault backend requires different errors than a pass backend which is different to a bitwarden backend or keepassxc backend. We can't possibly have just one error type for all of them. IMO the same way Backend is polymorphic over a, BackendError a should somehow also be polymorphic, i've yet to figure out why, thats why its in sucha sorry state right now. But the PR itself LGTM

dcastro commented 2 years ago

BackendError a should somehow also be polymorphic

@MagicRB does it need to be?

Backend is polymorphic because we need to abstract over it. But I don't see the need to abstract over the type of exception, we just need to bubble it up to main and then print it.

MagicRB commented 2 years ago

BackendError a should somehow also be polymorphic

@MagicRB does it need to be?

Backend is polymorphic because we need to abstract over it. But I don't see the need to abstract over the type of exception, we just need to bubble it up to main and then print it.

Because the frontend should be decoupled from the backend, that's the point of this architecture, if we add errors for all the backend we'll end up with a tight coupling between the two parts and a pattern matching mess somewhere.

MagicRB commented 2 years ago

The lowest common denominators for errors are showing them in some prettified sense and serializing into some unified data structure for human consumption. I also figured out another reason why this is a bad idea, as it stands now, the coffer client and server can have different backends available when running in #56 but if we add these backend specific errors we'll loose this decoupledness.

dcastro commented 2 years ago

Because the frontend should be decoupled from the backend, that's the point of this architecture, if we add errors for all the backend we'll end up with a tight coupling between the two parts and a pattern matching mess somewhere

Yeah I get that, what I'm saying is that CofferError doesn't need to be polymorphic (i.e. CofferError a) (unless I misunderstood your suggestion).

We could have a constructor that takes any printable error (basically, what you just said "The lowest common denominators for errors are showing them in some prettified sense and serializing into some unified data structure for human consumption")

data CofferError where
  ...
  BackendError :: Buildable err => err -> CofferError

Then you can have multiple backend-specific error types (VaultError, PassError, etc) and wrap them all in BackendError.

MagicRB commented 2 years ago
data CofferError where
  ...
  BackendError :: Buildable err => err -> CofferError

Then you can have multiple backend-specific error types (VaultError, PassError, etc) and wrap them all in BackendError. Sounds reasonable

dcastro commented 2 years ago

@MagicRB : I've created an issue for this: https://github.com/serokell/coffer/issues/72