80

In Ruby, is there a way to check if a string is valid json before trying to parse it?

For example getting some information from some other urls, sometimes it returns json, sometimes it could return a garbage which is not a valid response.

My code:

def get_parsed_response(response)
  parsed_response = JSON.parse(response)
end
8
  • 8
    I'm pretty sure parsing it is the only way to know for sure it's valid. Why not parse it and handle the parsing error telling you it's invalid? Commented Oct 7, 2014 at 9:35
  • 4
    for example this way JSON.parse(string) rescue nil Commented Oct 7, 2014 at 9:36
  • 1
    Theoretically, there should be a way. Parsing a string results in a properly stronger information than knowing whether it is parsable or not. In Chomsky's term, regarding natural language, this distinction corresponds to strong versus weak generative capacity. However, what's wrong with rescuing the error as with the comments above? Commented Oct 7, 2014 at 9:53
  • 2
    Or you could use a Regex to validate JSON Commented Oct 7, 2014 at 9:55
  • 1
    Technically speaking, the process of determining whether a string is valid in a language is parsing. Building a data-structure telling you how it is valid is actually just a side-effect of that. Commented Oct 7, 2014 at 10:50

5 Answers 5

93

You can create a method to do the checking:

def valid_json?(json)
  JSON.parse(json)
  true
rescue JSON::ParserError, TypeError => e
  false
end
Sign up to request clarification or add additional context in comments.

4 Comments

rescuing Exception is dangerous. It should only be used if absolutely necessary. Instead rescue several exceptions, like so: rescue TypeError, JSON::ParserError, etc.
no need to use "begin". def - rescue - end should work
Thank you Taufiq Muhammadi. Made my answer better.
You don't need the "return" either.
31

You can parse it this way

begin
  JSON.parse(string)  
rescue JSON::ParserError => e  
  # do smth
end 

# or for method get_parsed_response

def get_parsed_response(response)
  parsed_response = JSON.parse(response)
rescue JSON::ParserError => e  
  # do smth
end

1 Comment

Please note that there may be 'TypeError' if under <string> there would be something that cannot be implicitly converted to string(e.g. nil)
15

I think parse_json should return nil if it's invalid and shouldn't error out.

def parse_json string
  JSON.parse(string) rescue nil
end

unless json = parse_json string
  parse_a_different_way
end

2 Comments

Because its prettier... in fact, I'm considering opening up JSON and creating a method called parse_without_error.
Note that null and false are valid JSON, too. JSON.parse returns nil and false which would be treated as a parse error in the code above.
5

Let me suggest a shorter variant

def valid_json?(string)
  !!(JSON.parse(string) || true) rescue false
end

> valid_json?("test")
=> false

> valid_json?("{\"mail_id\": \"999129237\", \"public_id\": \"166118134802\"}")
=> true

> valid_json?("false")
=> true

Comments

0
def valid_json?(json)
  begin
    JSON.parse(json)
    return true
  rescue Exception => e
    return false
  end
end

answer here: https://gist.github.com/ascendbruce/7070951

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.