That being said, caching needs to be done at the resolution layer rather than the request layer. Under REST, APIs are generally modeled as returning individual objects or lists of one kind of object, which makes requests a reasonable thing to cache. Under GraphQL, each resolver returns a different type of content, and the mixed bag of content means that there should probably be different cache policies and invalidation for each kind of data provided by each resolver.
The status code being 200 even though your query is wrong or failed to correctly return data makes sense for the same reason. If you got a 500 because one field failed to correctly resolve, but the rest of the query was fine, the 500 is only telling you that something went wrong without letting you know exactly what it is. In GraphQL, we should save the status codes for request-level network issues rather than semantic issues with the request or the response.