Search code examples
jsonjqjson-rpc

json-rpc response jq filtering with multiple possible values


Can't figure how to filter jq output to show only result or error message from json-rpc response. Example response looks like this:

Normal:

{
  "result": "0001",
  "id": 1,
  "jsonrpc": "2.0"
}

Error:

{
  "error": {
    "code": -32000,
    "message": "Server error",
    "data": {
      "type": "TypeError",
      "args": [
        "'NoneType' object is not subscriptable"
      ],
      "message": "'NoneType' object is not subscriptable"
    }
  },
  "id": 1,
  "jsonrpc": "2.0"
}

I can access both of them alone, but don't know how to get 'or' function

$ ./reqok | jq .result
"0001"
$ ./reqbad | jq .error.data.message
"'NoneType' object is not subscriptable"

Solution

  • In jq you can use the alternate operator // that can be used to return default values. E.g. A filter of the form a // b produces the same results as a, if a produces results other than false and null. Otherwise, a // b produces the same results as b.

    Also useful for providing defaults: .foo // 1 will evaluate to 1 if there’s no .foo element in the input.

    jq '.result? // .error.data.message?'
    

    Note that this will only work when the the value of .result isn't null or false in which case also the execution goes the alternate condition.