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

An error returned by a `Linx.Capabilities` read operation.

Built from a failed `File.read/1` against `/proc/<pid>/status`,
or from a parser that couldn't make sense of the contents. The
shape:

  * `:path` — the procfs path the operation targeted.
  * `:operation` — what we were trying to do, as an atom. The
    read path uses `:read`; future operations would extend this.
  * `:errno` — the POSIX errno as an atom (`:enoent`, `:eacces`,
    …), or `:bad_status` if the file existed but didn't contain
    the five `Cap*:` lines we expected.
  * `:code` — the matching positive errno integer, or `nil` for
    atoms outside the POSIX table (`:bad_status` has `code: nil`).

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

    case Linx.Capabilities.read(pid) do
      {:ok, state} ->
        inspect(state)

      {:error, %Linx.Capabilities.Error{errno: :enoent}} ->
        # Target pid is gone.
        :pid_dead

      {:error, %Linx.Capabilities.Error{errno: :eacces}} ->
        # No permission to read /proc/<pid>/status — should be
        # rare; status is usually world-readable.
        :no_perm

      {:error, %Linx.Capabilities.Error{errno: :bad_status}} ->
        # The file existed but didn't have the expected Cap*:
        # lines. Should never happen on a real Linux kernel.
        :unparseable
    end

Pre-exec failures from the *write* side don't surface as
`%Linx.Capabilities.Error{}` — they come through
`Linx.Process`'s `{:linx_process, :error, errno, stage}` shape
with stage atoms like `:cap_drop_bounding`. This struct is for
the host-side read path only.

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

# `operation`

```elixir
@type operation() :: :read
```

# `t`

```elixir
@type t() :: %Linx.Capabilities.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.Capabilities.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*
