From cb1a632eaa91bff61a24c72d5c9ede20a5ca214f Mon Sep 17 00:00:00 2001 From: Brandon Vincent Date: Tue, 23 Dec 2025 12:35:04 -0800 Subject: [PATCH 1/3] Add default handler for non-JSON-serializable objects --- CHANGELOG.md | 7 ++++++- deps.edn | 5 +++-- src/clojure/dialog/format/json.clj | 9 +++++++++ test/dialog/format/json_test.clj | 11 ++++++++++- 4 files changed, 28 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8182f25..780eebc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,12 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] -... +### Changed +- The `:json` formatter now handles objects that aren't JSON serializiable + by calling `clojure.core/str` on them and writing the resulting string. + Previously, these values would cause the event to be dropped with a warning similar to + `[dialog output error] Failed to write to output stdout: Don't know how to write JSON of class `. +- Update `clojure.data.json` dependency. ## [2.0.115] - 2023-03-24 diff --git a/deps.edn b/deps.edn index eca0500..95509df 100644 --- a/deps.edn +++ b/deps.edn @@ -5,7 +5,7 @@ :deps {org.clojure/clojure {:mvn/version "1.11.1"} - org.clojure/data.json {:mvn/version "2.4.0"} + org.clojure/data.json {:mvn/version "2.5.1"} org.slf4j/slf4j-api {:mvn/version "2.0.7"} org.slf4j/jul-to-slf4j {:mvn/version "2.0.7"} org.slf4j/jcl-over-slf4j {:mvn/version "2.0.7"} @@ -43,7 +43,8 @@ :test {:extra-paths ["test"] - :extra-deps {lambdaisland/kaocha {:mvn/version "1.80.1274"}} + :extra-deps {lambdaisland/kaocha {:mvn/version "1.80.1274"} + clj-time/clj-time {:mvn/version "0.15.2"}} :jvm-opts ["-XX:-OmitStackTraceInFastThrow" "-Duser.language=en" "-Duser.country=US"] diff --git a/src/clojure/dialog/format/json.clj b/src/clojure/dialog/format/json.clj index d6ba881..671a97a 100644 --- a/src/clojure/dialog/format/json.clj +++ b/src/clojure/dialog/format/json.clj @@ -75,6 +75,14 @@ (str v)))) +(defn- default-write-fn + "Default write handler for any types that don't implement + `clojure.data.json/JSONWriter`: just calls `str` on the value and writes the + resulting string." + [value out options] + (json/-write (str value) out options)) + + (defn formatter "Construct a JSON event formatting function." [_output] @@ -84,4 +92,5 @@ event :key-fn key-fn :value-fn value-fn + :default-write-fn default-write-fn :escape-slash false))) diff --git a/test/dialog/format/json_test.clj b/test/dialog/format/json_test.clj index 6b81824..bd60299 100644 --- a/test/dialog/format/json_test.clj +++ b/test/dialog/format/json_test.clj @@ -2,6 +2,7 @@ (:require [clojure.string :as str] [clojure.test :refer [deftest testing is]] + [clj-time.core :as time] [dialog.format.json :as json]) (:import java.time.Instant)) @@ -43,4 +44,12 @@ (testing "throwables" (let [ex (RuntimeException. "BOOM") message (fmt {:error ex})] - (is (str/starts-with? message "{\"error\":[{\"class-name\":\"java.lang.RuntimeException\",")))))) + (is (str/starts-with? message "{\"error\":[{\"class-name\":\"java.lang.RuntimeException\",")))) + (testing "types that don't implement JSONWriter" + (let [date-time (time/date-time 2025 5 5) + event {:date-time date-time}] + (with-redefs [json/default-write-fn (fn [& _] (throw (Exception. "default-write-fn called")))] + (is (thrown? Exception #"^default-write-fn called$" + (fmt event)))) + (is (= "{\"date-time\":\"2025-05-05T00:00:00.000Z\"}" + (fmt {:date-time date-time}))))))) From 63d46893b91a24be77a7747bcbc37227455ef4fa Mon Sep 17 00:00:00 2001 From: Brandon Vincent Date: Tue, 23 Dec 2025 12:38:05 -0800 Subject: [PATCH 2/3] cljstyle and typo --- CHANGELOG.md | 2 +- test/dialog/format/json_test.clj | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 780eebc..2363d6c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] ### Changed -- The `:json` formatter now handles objects that aren't JSON serializiable +- The `:json` formatter now handles objects that aren't JSON serializable by calling `clojure.core/str` on them and writing the resulting string. Previously, these values would cause the event to be dropped with a warning similar to `[dialog output error] Failed to write to output stdout: Don't know how to write JSON of class `. diff --git a/test/dialog/format/json_test.clj b/test/dialog/format/json_test.clj index bd60299..9f0d4a7 100644 --- a/test/dialog/format/json_test.clj +++ b/test/dialog/format/json_test.clj @@ -1,8 +1,8 @@ (ns dialog.format.json-test (:require + [clj-time.core :as time] [clojure.string :as str] [clojure.test :refer [deftest testing is]] - [clj-time.core :as time] [dialog.format.json :as json]) (:import java.time.Instant)) @@ -50,6 +50,6 @@ event {:date-time date-time}] (with-redefs [json/default-write-fn (fn [& _] (throw (Exception. "default-write-fn called")))] (is (thrown? Exception #"^default-write-fn called$" - (fmt event)))) + (fmt event)))) (is (= "{\"date-time\":\"2025-05-05T00:00:00.000Z\"}" (fmt {:date-time date-time}))))))) From 5c9ffc784aaa16f83b4592ee6069f9bacdb10743 Mon Sep 17 00:00:00 2001 From: Brandon Vincent Date: Tue, 23 Dec 2025 12:43:14 -0800 Subject: [PATCH 3/3] Fix coverage? --- deps.edn | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/deps.edn b/deps.edn index 95509df..ffeccf3 100644 --- a/deps.edn +++ b/deps.edn @@ -52,7 +52,8 @@ :coverage {:extra-paths ["test"] - :extra-deps {cloverage/cloverage {:mvn/version "RELEASE"}} + :extra-deps {cloverage/cloverage {:mvn/version "RELEASE"} + clj-time/clj-time {:mvn/version "0.15.2"}} :jvm-opts ["-Duser.language=en" "-Duser.country=US"] :main-opts ["-m" "cloverage.coverage"