Skip to content

fix: Fix Railtie middleware insertion crashing on Rails initialization#98

Open
johnnagro wants to merge 8 commits intoPostHog:mainfrom
noreastergroup:johnnagro/issue-97/0
Open

fix: Fix Railtie middleware insertion crashing on Rails initialization#98
johnnagro wants to merge 8 commits intoPostHog:mainfrom
noreastergroup:johnnagro/issue-97/0

Conversation

@johnnagro
Copy link
Contributor

@johnnagro johnnagro commented Feb 6, 2026

fixes #97, #87, #88

Fixes initializer middleware errors #97

The initializer block called insert_middleware_after as a class method, but Rails runs initializer blocks via instance_exec on the Railtie instance. Also removed the include? check on MiddlewareStackProxy which doesn't support query methods during initialization.

I created a fresh rails project, added posthog-ruby and the local copy of this posthog-rails branch. Then verified that bin/rails generate posthog:install runs cleanly again.

Fixes Exception capture payload & Empty Batch Errors #87

Also fixes when a message exceeds the 32KB size limit, it is silently dropped from the batch. Previously the worker would still send the empty batch to the API, which returned a non-JSON response, causing a JSON::ParserError
that triggered 10 pointless retries.

  • Skip transport request when the batch is empty after consuming the queue
  • Rescue JSON::ParserError in Transport#send and fall back to the raw
    response body instead of crashing

Only include source context lines for in-app exception frames #88

Exception payloads frequently exceeded the 32KB message limit because
context lines (11 lines of source code) were read for every stack frame,
including gem and framework frames. A typical Rails backtrace has ~50
frames, most from Rails internals, easily blowing past the limit and
causing the event to be silently dropped.

Now context lines are only added for in_app frames. Gem/framework frames
still include file, line number, and function name.

Fixes Use $current_url property so exception URL appears in PostHog UI

The CaptureExceptions middleware was setting $request_url, which is not
recognized by PostHog for the "URL / Screen" column. Renamed to
$current_url to match the standard property used across PostHog SDKs.

Screen Shot 2026-02-06 at 3 45 49 PM

The initializer block called insert_middleware_after as a class method,
but Rails runs initializer blocks via instance_exec on the Railtie
instance. Also removed the include? check on MiddlewareStackProxy which
doesn't support query methods during initialization.
When a message exceeds the 32KB size limit, it is silently dropped from
the batch. Previously the worker would still send the empty batch to the
API, which returned a non-JSON response, causing a JSON::ParserError
that triggered 10 pointless retries.

- Skip transport request when the batch is empty after consuming the queue
- Rescue JSON::ParserError in Transport#send and fall back to the raw
  response body instead of crashing
The CaptureExceptions middleware was setting $request_url, which is not
recognized by PostHog for the "URL / Screen" column. Renamed to
$current_url to match the standard property used across PostHog SDKs.
Exception payloads frequently exceeded the 32KB message limit because
context lines (11 lines of source code) were read for every stack frame,
including gem and framework frames. A typical Rails backtrace has ~50
frames, most from Rails internals, easily blowing past the limit and
causing the event to be silently dropped.

Now context lines are only added for in_app frames. Gem/framework frames
still include file, line number, and function name.

Fixes PostHog#88
Copy link
Member

@rafaeelaudibert rafaeelaudibert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @johnnagro , those all are really good fixes! Do you mind adding them to the CHANGELOG so that we can release them? Also, do you mind bumping PostHog::VERSION by one patch version?

We'll be improving this slightly in the future but, for now, that's how we're handling this. Or you can give me access to your repo and I can do it myself

Also, rubocop is complaining

@johnnagro
Copy link
Contributor Author

@rafaeelaudibert i'm happy to help. I've made the changes you've requested. At your convenience please take another look and let me know if you'd like me to make any additional tweaks.

# Fallback: append to stack if target middleware is missing (e.g., API-only apps)
app.config.middleware.use(middleware)
end
def insert_middleware_after(app, target, middleware)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a problem here, though. If target doesn't exist then we won't insert our middleware, and that's a bad failure. I wonder if there's a better way. Will keep it like this for now, but I'll keep thinking about it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agreed - i opened #99 and we can think through a more robust approach

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

NoMethodError: undefined method 'insert_middleware_after' in Railtie initializer

2 participants