diff --git a/src/Prometheus.jl b/src/Prometheus.jl index ce5433e..64f181e 100644 --- a/src/Prometheus.jl +++ b/src/Prometheus.jl @@ -13,16 +13,32 @@ abstract type Collector end abstract type PrometheusException <: Exception end -struct PrometheusUnreachable <: PrometheusException end -unreachable() = throw(PrometheusUnreachable()) +struct ArgumentError <: PrometheusException + msg::String +end +function Base.showerror(io::IO, err::ArgumentError) + print(io, "Prometheus.", nameof(typeof(err)), ": ", err.msg) +end -struct PrometheusAssert <: PrometheusException end +struct UnreachableError <: PrometheusException end +unreachable() = throw(UnreachableError()) + +struct AssertionError <: PrometheusException end macro assert(cond) return quote - $(esc(cond)) || throw(PrometheusAssert()) + $(esc(cond)) || throw(AssertionError()) end end +function Base.showerror(io::IO, err::Union{AssertionError, UnreachableError}) + print( + io, + "Prometheus.", nameof(typeof(err)), + ": this is unexpected. Please file an issue at " * + "https://github.com/fredrikekre/Prometheus.jl/issues/new", + ) +end + ########################################### # Compat for const fields, @lock, @atomic # ########################################### @@ -75,8 +91,12 @@ function register(reg::CollectorRegistry, collector::Collector) for c in reg.collectors union!(existing_names, metric_names(c)) end - if any(in(existing_names), metric_names(collector)) - error("not allowed") + for metric_name in metric_names(collector) + if metric_name in existing_names + throw(ArgumentError( + "collector already contains a metric with the name \"$(metric_name)\"" + )) + end end push!(reg.collectors, collector) end @@ -151,12 +171,15 @@ end """ Prometheus.inc(counter::Counter, v = 1) -Increment the value of the counter with `v`. -`v` must be non-negative, and defaults to `v = 1`. +Increment the value of the counter with `v`. The value defaults to `v = 1`. + +Throw a `Prometheus.ArgumentError` if `v < 0` (a counter must not decrease). """ function inc(counter::Counter, v = 1.0) if v < 0 - error("counting backwards") + throw(ArgumentError( + "invalid value $v: a counter must not decrease" + )) end @atomic counter.value += v return nothing @@ -507,7 +530,7 @@ function collect!(metrics::Vector, family::Family{C}) where C for (labels, child) in family.children # collect!(...) the child, throw away the metric, but keep the samples child_metrics = collect!(resize!(buf, 0), child) - length(child_metrics) !=1 && error("multiple metrics not supported (yet?)") + length(child_metrics) != 1 && unreachable() # TODO: maybe this should be supported? child_metric = child_metrics[1] @assert(child_metric.type == type) # Unwrap and rewrap samples with the labels diff --git a/test/runtests.jl b/test/runtests.jl index 0b20873..75fdb1e 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -7,7 +7,10 @@ using Test: @test, @test_logs, @test_throws, @testset # Default registry c = Prometheus.Counter("metric_name_counter", "A counter.") @test c in Prometheus.DEFAULT_REGISTRY.collectors - @test_throws ErrorException Prometheus.Counter("metric_name_counter", "A counter.") + @test_throws( + Prometheus.ArgumentError("collector already contains a metric with the name \"metric_name_counter\""), + Prometheus.Counter("metric_name_counter", "A counter."), + ) Prometheus.unregister(Prometheus.DEFAULT_REGISTRY, c) @test !(c in Prometheus.DEFAULT_REGISTRY.collectors) c2 = Prometheus.Counter("metric_name_counter", "A counter.") @@ -23,7 +26,10 @@ using Test: @test, @test_logs, @test_throws, @testset r = Prometheus.CollectorRegistry() Prometheus.register(r, c) @test c in r.collectors - @test_throws ErrorException Prometheus.register(r, c) + @test_throws( + Prometheus.ArgumentError("collector already contains a metric with the name \"metric_name_counter\""), + Prometheus.register(r, c), + ) end @testset "Prometheus.Counter" begin @@ -42,7 +48,7 @@ end @test c.value == 1 Prometheus.inc(c, 2) @test c.value == 3 - @test_throws ErrorException Prometheus.inc(c, -1) + @test_throws Prometheus.ArgumentError Prometheus.inc(c, -1) # Prometheus.collect(...) metrics = Prometheus.collect(c) @test length(metrics) == 1 @@ -472,7 +478,13 @@ end end @testset "Utilities" begin - @test_throws Prometheus.PrometheusUnreachable Prometheus.unreachable() - @test_throws Prometheus.PrometheusAssert Prometheus.@assert false - @test_throws Prometheus.PrometheusUnreachable Prometheus.prometheus_type(Int) + @test_throws Prometheus.UnreachableError Prometheus.unreachable() + @test_throws Prometheus.AssertionError Prometheus.@assert false + @test occursin("unexpected", sprint(showerror, Prometheus.UnreachableError())) + @test occursin("unexpected", sprint(showerror, Prometheus.AssertionError())) + @test occursin( + "Prometheus.ArgumentError: err", + sprint(showerror, Prometheus.ArgumentError("err")), + ) + @test_throws Prometheus.UnreachableError Prometheus.prometheus_type(Int) end