# `Linx.User.Error`
[🔗](https://github.com/oshlabs/linx/blob/v0.2.0/lib/linx/user/error.ex#L1)

An error returned by a `Linx.User` operation.

Built from a failed `File.read/1` / `File.write/2` against one of
the user-namespace procfs files (`/proc/<pid>/uid_map`,
`/proc/<pid>/gid_map`, `/proc/<pid>/setgroups`). The shape:

  * `:path` — the procfs path the operation targeted.
  * `:operation` — what we were trying to do, as an atom
    (`:set_uid_map`, `:set_gid_map`, `:deny_setgroups`,
    `:read_uid_map`, `:read_gid_map`).
  * `:errno` — the POSIX errno as an atom (`:enoent`, `:eperm`,
    `:einval`, …).
  * `:code` — the matching positive errno integer, or `nil` if
    we don't have a mapping for this atom. Included for symmetry
    with `Linx.Mount.Error` / `Linx.Cgroup.Error`.

Pattern-match on `:errno` and `:operation` to handle specific
failures:

    case Linx.User.set_uid_map(pid, [{0, 1000, 1}]) do
      :ok ->
        :mapped

      {:error, %Linx.User.Error{errno: :eperm}} ->
        # No CAP_SETUID in the parent user ns; the map is too
        # broad for an unprivileged caller, or the map was
        # already written (write-once).
        :no_perm

      {:error, %Linx.User.Error{errno: :enoent}} ->
        # The target pid is gone.
        :pid_dead
    end

Implements `Exception`, so an error can be `raise`d or rendered
with `Exception.message/1`.

Caller-side input mistakes (e.g. a non-list `mappings`,
negative ids, zero-length entries) surface as
`{:error, {:bad_map, reason}}` instead — distinct from kernel
rejections, mirroring `Linx.Mount`'s `:bad_flag` / `%Error{}`
split.

# `operation`

```elixir
@type operation() ::
  :set_uid_map | :set_gid_map | :deny_setgroups | :read_uid_map | :read_gid_map
```

# `t`

```elixir
@type t() :: %Linx.User.Error{
  __exception__: true,
  code: pos_integer() | nil,
  errno: atom(),
  operation: operation(),
  path: Path.t()
}
```

# `from_posix`

```elixir
@spec from_posix(atom(), Path.t(), operation()) :: t()
```

Builds a `%Linx.User.Error{}` from a posix-atom errno, the
procfs path that failed, and the operation we attempted.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
