Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use our own JSON encoder #118

Merged
merged 6 commits into from
Jul 10, 2013
Merged

Use our own JSON encoder #118

merged 6 commits into from
Jul 10, 2013

Conversation

zimbatm
Copy link
Contributor

@zimbatm zimbatm commented Jul 8, 2013

The goal of raven is to report exceptions. By introducing our own tuned version of OkJson that coerces values to a serialisable state we can guarantee that a JSON is going to be generated.

This branch fixes #97.

It also avoids issues with ActiveRecord's #to_json/#as_json that trigger "IOError: not opened for reading" when serialising an IO (like the rack.input)

@nateberkopec
Copy link
Contributor

Wasn't this fixed by #107? I much prefer allowing users to select their own adapter rather then to force them to use our vendored one.

@zimbatm
Copy link
Contributor Author

zimbatm commented Jul 9, 2013

Nope, #107 defers the decision to the user which will have to discover
himself what adapter works best with the kind of data sentry is sending
(answer: none).

Given that the goal of sentry is to report exception I believe that it's
more important to have something working all the time than provide a fake
choice.
On Jul 9, 2013 12:13 AM, "Nate Berkopec" notifications@github.com wrote:

Wasn't this fixed by #107#107?
I much prefer allowing users to select their own adapter rather then to
force them to use our vendored one.


Reply to this email directly or view it on GitHubhttps://github.com//pull/118#issuecomment-20643174
.

Jonas Pfenniger added 2 commits July 9, 2013 11:46
Circular dependencies and JSON serialization don't play well together.
Depending on the library it might throw a SystemStackTooDeep or even segfault
the interpreter.

Here we replace the circular depency with a "[...]" or "{...}" string
representation that should make it clear later on what happened.
@zimbatm
Copy link
Contributor Author

zimbatm commented Jul 10, 2013

Ok so as a recap: commit 19d3810 + 05eff65 fixes circular references on the given input by replacing them with a string.

BUT, if any adapter uses #as_json / #to_json, additional structures might get generated later on that might themselves contain circular references. This is the case for at least ActiveRecord::JSON and the json gem, maybe others.

This is an issue because we cannot guarantee that the input data is clean and JSON-compatible. The rack env can contain arbitrary data and is in practice used to exchange data between various middlewares. Because we want to report and exception it is important that the JSON generation doesn't fail.

On a side note, ActiveRecord defines Enumerable#as_json which coerces the data with #to_a. IO objects are Enumerable and #to_a reads the file. This means that IO objects are read completely when generating the JSON which might either lead to a big payload or an exception if the IO object is not opened for read.
ActiveRecord also defines Object#as_json to unpack all the instance variables which also doesn't help for circular references issues as it's common to keep references between objects in a tree-like structure.

So in conclusion, the last two commits are probably good to have anyways. I also propose that we use our own version of OkJson that favours coercion over exception but it's probably also possible to use another external library if it satisfies our needs. I also believe that choosing one JSON generator will lead to less support issues that are hard to debug.

@nateberkopec
Copy link
Contributor

Thanks for making the whole issue clear, @zimbatm.

So, overall, for me:

The json_adapter configuration setting, as shipping right now, breaks for fairly common use cases in Rails environments (as you wrote above) or other apps using ActiveRecord. Your PR fixes this by shipping a specialized adapter that prefers coercion over exception, which is unusual but appropriate for this use case (we'd rather send an incomplete exception than no exception at all). It is difficult to debug because you may not even be aware that it's happening (silent failure).

So we're trading configurability (multi_json) for stability (vendored OkJson). Still haven't decided if I'm ok with this tradeoff or not - @dcramer? Others?

@dcramer
Copy link
Member

dcramer commented Jul 10, 2013

Configurability is overrated IMO

@nateberkopec
Copy link
Contributor

Good enough for me, then. Thanks again @zimbatm for writing such a clear explanation of the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Circular references exhaust available stack space
3 participants