Skip to content
Snippets Groups Projects
Commit 39420403 authored by Iustin Pop's avatar Iustin Pop
Browse files

luxi backend: show attribute names in errors


Currently, this backend just gives:

  Error: failed to load data. Details:
  Node 'node2': Cannot convert value JSNull, error: Unable to read Double

That is because for Luxi we get an array back from the query, as
opposed to RAPI where we get a dict (and thus have the key at
hand). This patch moves the hardcoded 'convert' functions to a
genericConvert, that also takes the attribute name, with the result
that the error message is now:

  Error: failed to load data. Details:
  Node 'node2', attribute 'mtotal': Cannot convert value 'JSNull', error: Unable to read Double

which is better for debugging.

The patch also adds quotes around the value in the Utils.fromJVal
function.

Signed-off-by: default avatarIustin Pop <iustin@google.com>
Reviewed-by: default avatarAdeodato Simo <dato@google.com>
parent 6656790a
No related branches found
No related tags found
No related merge requests found
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
{- {-
Copyright (C) 2009, 2010 Google Inc. Copyright (C) 2009, 2010, 2011 Google Inc.
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
...@@ -31,6 +31,7 @@ module Ganeti.HTools.Luxi ...@@ -31,6 +31,7 @@ module Ganeti.HTools.Luxi
import qualified Control.Exception as E import qualified Control.Exception as E
import Text.JSON.Types import Text.JSON.Types
import qualified Text.JSON
import qualified Ganeti.Luxi as L import qualified Ganeti.Luxi as L
import Ganeti.HTools.Loader import Ganeti.HTools.Loader
...@@ -49,6 +50,18 @@ toArray v = ...@@ -49,6 +50,18 @@ toArray v =
JSArray arr -> return arr JSArray arr -> return arr
o -> fail ("Invalid input, expected array but got " ++ show o) o -> fail ("Invalid input, expected array but got " ++ show o)
-- | Annotate errors when converting values with owner/attribute for
-- better debugging.
genericConvert :: (Text.JSON.JSON a) =>
String -- ^ The object type
-> String -- ^ The object name
-> String -- ^ The attribute we're trying to convert
-> JSValue -- ^ The value we try to convert
-> Result a -- ^ The annotated result
genericConvert otype oname oattr =
annotateResult (otype ++ " '" ++ oname ++ "', attribute '" ++
oattr ++ "'") . fromJVal
-- * Data querying functionality -- * Data querying functionality
-- | The input data for node query. -- | The input data for node query.
...@@ -101,18 +114,18 @@ parseInstance :: NameAssoc ...@@ -101,18 +114,18 @@ parseInstance :: NameAssoc
parseInstance ktn (JSArray [ name, disk, mem, vcpus parseInstance ktn (JSArray [ name, disk, mem, vcpus
, status, pnode, snodes, tags, oram ]) = do , status, pnode, snodes, tags, oram ]) = do
xname <- annotateResult "Parsing new instance" (fromJVal name) xname <- annotateResult "Parsing new instance" (fromJVal name)
let convert v = annotateResult ("Instance '" ++ xname ++ "'") (fromJVal v) let convert a = genericConvert "Instance" xname a
xdisk <- convert disk xdisk <- convert "disk_usage" disk
xmem <- (case oram of xmem <- (case oram of
JSRational _ _ -> convert oram JSRational _ _ -> convert "oper_ram" oram
_ -> convert mem) _ -> convert "be/memory" mem)
xvcpus <- convert vcpus xvcpus <- convert "be/vcpus" vcpus
xpnode <- convert pnode >>= lookupNode ktn xname xpnode <- convert "pnode" pnode >>= lookupNode ktn xname
xsnodes <- convert snodes::Result [JSString] xsnodes <- convert "snodes" snodes::Result [JSString]
snode <- (if null xsnodes then return Node.noSecondary snode <- (if null xsnodes then return Node.noSecondary
else lookupNode ktn xname (fromJSString $ head xsnodes)) else lookupNode ktn xname (fromJSString $ head xsnodes))
xrunning <- convert status xrunning <- convert "status" status
xtags <- convert tags xtags <- convert "tags" tags
let inst = Instance.create xname xmem xdisk xvcpus let inst = Instance.create xname xmem xdisk xvcpus
xrunning xtags xpnode snode xrunning xtags xpnode snode
return (xname, inst) return (xname, inst)
...@@ -129,20 +142,20 @@ parseNode ktg (JSArray [ name, mtotal, mnode, mfree, dtotal, dfree ...@@ -129,20 +142,20 @@ parseNode ktg (JSArray [ name, mtotal, mnode, mfree, dtotal, dfree
, ctotal, offline, drained, vm_capable, g_uuid ]) , ctotal, offline, drained, vm_capable, g_uuid ])
= do = do
xname <- annotateResult "Parsing new node" (fromJVal name) xname <- annotateResult "Parsing new node" (fromJVal name)
let convert v = annotateResult ("Node '" ++ xname ++ "'") (fromJVal v) let convert a = genericConvert "Node" xname a
xoffline <- convert offline xoffline <- convert "offline" offline
xdrained <- convert drained xdrained <- convert "drained" drained
xvm_capable <- convert vm_capable xvm_capable <- convert "vm_capable" vm_capable
xgdx <- convert g_uuid >>= lookupGroup ktg xname xgdx <- convert "group.uuid" g_uuid >>= lookupGroup ktg xname
node <- (if xoffline || xdrained || not xvm_capable node <- (if xoffline || xdrained || not xvm_capable
then return $ Node.create xname 0 0 0 0 0 0 True xgdx then return $ Node.create xname 0 0 0 0 0 0 True xgdx
else do else do
xmtotal <- convert mtotal xmtotal <- convert "mtotal" mtotal
xmnode <- convert mnode xmnode <- convert "mnode" mnode
xmfree <- convert mfree xmfree <- convert "mfree" mfree
xdtotal <- convert dtotal xdtotal <- convert "dtotal" dtotal
xdfree <- convert dfree xdfree <- convert "dfree" dfree
xctotal <- convert ctotal xctotal <- convert "ctotal" ctotal
return $ Node.create xname xmtotal xmnode xmfree return $ Node.create xname xmtotal xmnode xmfree
xdtotal xdfree xctotal False xgdx) xdtotal xdfree xctotal False xgdx)
return (xname, node) return (xname, node)
...@@ -161,9 +174,9 @@ getGroups arr = toArray arr >>= mapM parseGroup ...@@ -161,9 +174,9 @@ getGroups arr = toArray arr >>= mapM parseGroup
parseGroup :: JSValue -> Result (String, Group.Group) parseGroup :: JSValue -> Result (String, Group.Group)
parseGroup (JSArray [ uuid, name, apol ]) = do parseGroup (JSArray [ uuid, name, apol ]) = do
xname <- annotateResult "Parsing new group" (fromJVal name) xname <- annotateResult "Parsing new group" (fromJVal name)
let convert v = annotateResult ("Node '" ++ xname ++ "'") (fromJVal v) let convert a = genericConvert "Group" xname a
xuuid <- convert uuid xuuid <- convert "uuid" uuid
xapol <- convert apol xapol <- convert "alloc_policy" apol
return $ (xuuid, Group.create xname xuuid xapol) return $ (xuuid, Group.create xname xuuid xapol)
parseGroup v = fail ("Invalid group query result: " ++ show v) parseGroup v = fail ("Invalid group query result: " ++ show v)
......
...@@ -168,7 +168,8 @@ tryFromObj t o = annotateResult t . fromObj o ...@@ -168,7 +168,8 @@ tryFromObj t o = annotateResult t . fromObj o
fromJVal :: (Monad m, J.JSON a) => J.JSValue -> m a fromJVal :: (Monad m, J.JSON a) => J.JSValue -> m a
fromJVal v = fromJVal v =
case J.readJSON v of case J.readJSON v of
J.Error s -> fail ("Cannot convert value " ++ show v ++ ", error: " ++ s) J.Error s -> fail ("Cannot convert value '" ++ show v ++
"', error: " ++ s)
J.Ok x -> return x J.Ok x -> return x
-- | Converts a JSON value into a JSON object. -- | Converts a JSON value into a JSON object.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment