# `GcpCompute.TokenProvider.Goth`
[🔗](https://github.com/nyo16/gcp_compute/blob/v0.3.0/lib/gcp_compute/token_provider/goth.ex#L1)

`GcpCompute.TokenProvider` backed by [Goth](https://hexdocs.pm/goth).

The `arg` is the name a Goth server was started under:

    children = [
      {Goth, name: MyApp.Goth},
      # ...
    ]

    {:ok, config} =
      GcpCompute.Config.new(
        project: "my-project",
        token_provider: {GcpCompute.TokenProvider.Goth, MyApp.Goth}
      )

Goth is an *optional* dependency. If it isn't loaded, `fetch_token/1` returns
`{:error, %GcpCompute.Error{reason: :goth_not_available}}` instead of raising
at compile time.

## Process-liveness failures are errors, not exits

`Goth.fetch/1` is a `GenServer.call` through a `Registry`. When the named
server is missing it *exits* `:noproc`, and when the `:goth` application
itself isn't started `Registry.lookup/2` raises `ArgumentError`. Either one
would tear down the calling process — a `Task`, a `GenServer`, or a Phoenix
request — from inside what the caller believes is a `{:ok, _} | {:error, _}`
function. This module contains both at its boundary and returns
`:goth_not_running` / `:goth_fetch_timeout` instead.

Goth's `GenServer.call` timeout is its own hard-coded 5 s and is deliberately
**not** exposed as a knob here: it is an internal of an optional dependency,
a `:goth_fetch_timeout` is always a supervision or credentials problem rather
than something to wait longer for, and a token fetch sits on the hot path of
every request. Configure caching/refresh on the Goth server instead.

---

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