This fixes two problems:

- first, when we deserialise a big object, showing its value is not
  useful, as it will hide the actual error message
- second, we shouldn't deserialise a container at once, because then
  we will lose the detail of which 'key' failed to deserialise; we
  change to manual deserialisation of each key/value pair, so that we
  can keep this information

The last point requires that we import JSON.hs into THH.hs, in order
not to duplicate functionality.
---
 htools/Ganeti/HTools/JSON.hs |    3 ++-
 htools/Ganeti/THH.hs         |   10 ++++++++--
 2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/htools/Ganeti/HTools/JSON.hs b/htools/Ganeti/HTools/JSON.hs
index 6fe45ba..185201f 100644
--- a/htools/Ganeti/HTools/JSON.hs
+++ b/htools/Ganeti/HTools/JSON.hs
@@ -29,6 +29,7 @@ module Ganeti.HTools.JSON
   , fromObj
   , maybeFromObj
   , fromObjWithDefault
+  , fromKeyValue
   , fromJVal
   , asJSObject
   , asObjectList
@@ -95,7 +96,7 @@ fromKeyValue :: (J.JSON a, Monad m)
               -> J.JSValue  -- ^ The value to read
               -> m a
 fromKeyValue k val =
-  fromJResult (printf "key '%s', value '%s'" k (show val)) (J.readJSON val)
+  fromJResult (printf "key '%s'" k) (J.readJSON val)
 
 -- | Small wrapper over readJSON.
 fromJVal :: (Monad m, J.JSON a) => J.JSValue -> m a
diff --git a/htools/Ganeti/THH.hs b/htools/Ganeti/THH.hs
index 102ef49..cd43c20 100644
--- a/htools/Ganeti/THH.hs
+++ b/htools/Ganeti/THH.hs
@@ -63,6 +63,8 @@ import Language.Haskell.TH
 
 import qualified Text.JSON as JSON
 
+import Ganeti.HTools.JSON
+
 -- * Exported types
 
 type Container = M.Map String
@@ -205,8 +207,12 @@ appFn f x | f == VarE 'id = x
           | otherwise = AppE f x
 
 -- | Container loader
-readContainer :: (Monad m) => JSON.JSObject a -> m (Container a)
-readContainer = return . M.fromList . JSON.fromJSObject
+readContainer :: (Monad m, JSON.JSON a) =>
+                 JSON.JSObject JSON.JSValue -> m (Container a)
+readContainer obj = do
+  let kjvlist = JSON.fromJSObject obj
+  kalist <- mapM (\(k, v) -> fromKeyValue k v >>= \a -> return (k, a)) kjvlist
+  return $ M.fromList kalist
 
 -- | Container dumper
 showContainer :: (JSON.JSON a) => Container a -> JSON.JSValue
-- 
1.7.3.1

Reply via email to