{"record":{"id":"b55ab568eda79d97","repo":"apache/iceberg","slug":"noop-timer-has-no-count","errorCode":null,"errorMessage":"NOOP timer has no count","messagePattern":"NOOP timer has no count","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"api/src/main/java/org/apache/iceberg/metrics/Timer.java","lineNumber":140,"sourceCode":"\n    @Override\n    default void close() {\n      stop();\n    }\n\n    Timed NOOP = () -> {};\n  }\n\n  Timer NOOP =\n      new Timer() {\n        @Override\n        public Timed start() {\n          return Timed.NOOP;\n        }\n\n        @Override\n        public long count() {\n          throw new UnsupportedOperationException(\"NOOP timer has no count\");\n        }\n\n        @Override\n        public Duration totalDuration() {\n          throw new UnsupportedOperationException(\"NOOP timer has no duration\");\n        }\n\n        @Override\n        public TimeUnit unit() {\n          throw new UnsupportedOperationException(\"NOOP timer has no unit\");\n        }\n\n        @Override\n        public void record(long amount, TimeUnit unit) {}\n\n        @Override\n        public void time(Runnable runnable) {}\n","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/api/src/main/java/org/apache/iceberg/metrics/Timer.java#L122-L158","documentation":"The NOOP Timer (returned by Timer.NOOP) deliberately discards all recorded timings and exposes no measurement state. Calling count() on it throws UnsupportedOperationException because there is no accumulated count to report. This is by design: code instrumented with the NOOP timer must never read metrics back from it.","triggerScenarios":"Calling Timer.NOOP.count() directly, or calling count() on a Timer returned from Timer.Timed.NOOP-backed code paths when metrics are disabled (e.g. MetricsUtil/Timers constructed without an implementation).","commonSituations":"Developers writing generic code that records timings and later reads count() for logging/commit reports while the application runs with the NOOP metrics implementation; unit tests that assert on timer output without wiring a real metrics implementation.","solutions":["Use a real Timer implementation (e.g. DefaultTimer via Timer.of / Metrics context) instead of Timer.NOOP when you need to read count().","Guard the read: only call count() when you know the timer is not the NOOP instance (e.g. check timer != Timer.NOOP).","Treat NOOP as write-only instrumentation; derive counts yourself if you need them (count invocations manually)."],"exampleFix":"// before\nlong n = timer.count();\n// after\nlong n = (timer == Timer.NOOP) ? 0L : timer.count();","handlingStrategy":"type-guard","validationCode":"boolean readable = timer != Timer.NOOP;","typeGuard":"if (timer == Timer.NOOP) { return 0L; } return timer.count();","tryCatchPattern":"try { return timer.count(); } catch (UnsupportedOperationException e) { return 0L; }","preventionTips":["Never read metrics from Timer.NOOP; treat it as write-only","Wire a real metrics implementation (Timer.of) when counts are consumed","Add assertions in tests that timer != Timer.NOOP before reads"],"tags":["java","metrics","unsupported-operation","noop"],"backgroundTag":"unsupported-operation","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}