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

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

Built from a failed `File.read/1` / `File.write/2` against a
`/proc/sys/...` path, or — for the cross-namespace verbs —
from a failure during the setns dance the NIF performs on a
throwaway pthread.

The shape:

  * `:key` — the dot-form sysctl key the caller passed in, e.g.
    `"net.ipv4.ip_forward"`.
  * `:path` — the resolved procfs path the operation targeted,
    e.g. `"/proc/sys/net/ipv4/ip_forward"`.
  * `:operation` — what we were trying to do, as an atom:
    * `:read`, `:write`, `:list` — the procfs I/O itself failed.
    * `:open_ns`, `:unshare`, `:setns`, `:chdir`, `:thread` —
      namespace-acquisition failures from the cross-namespace NIF (only seen
      when a cross-namespace `:in` option was used).
  * `:errno` — the POSIX errno as an atom (`:enoent`, `:eperm`,
    `:eacces`, `: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.User.Error` / `Linx.Cgroup.Error`.

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

    case Linx.Sysctl.write("net.ipv4.ip_forward", 1) do
      :ok ->
        :ok

      {:error, %Linx.Sysctl.Error{errno: :eacces}} ->
        # Needs root.
        :no_perm

      {:error, %Linx.Sysctl.Error{errno: :enoent}} ->
        # No such sysctl on this kernel.
        :unknown_knob
    end

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

Caller-side input mistakes (a malformed key, a multi-line value
the kernel would silently truncate) surface as
`{:error, {:bad_key, reason}}` / `{:error, {:bad_value, reason}}`
instead — distinct from kernel rejections, mirroring
`Linx.User`'s `:bad_map` / `%Error{}` split.

# `operation`

```elixir
@type operation() ::
  :read | :write | :list | :open_ns | :unshare | :setns | :chdir | :thread
```

# `t`

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

# `from_posix`

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

Builds a `%Linx.Sysctl.Error{}` from a posix-atom errno, the
dot-form key, the resolved procfs path, and the operation we
attempted.

---

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