Embedding comments widget on localhost causes FrozenError

I have a rails site running on localhost:5000 and a local Discourse server is running on localhost:3000. I want to enable comments on articles (which is a rails resource in my case), so I’ve set up an embeddable host in the Discourse admin panel:

This is the script snippet I’ve added on my rails view:

<div id='discourse-comments'></div>

<script type="text/javascript">
  DiscourseEmbed = { discourseUrl: 'http://localhost:3000/',
                 discourseEmbedUrl: '<%= "http://localhost:5000/articles/#{@article.id}" %>'};

  (function() {
   var d = document.createElement('script'); d.type = 'text/javascript'; d.async = true;
   d.src = DiscourseEmbed.discourseUrl + 'javascripts/embed.js';
   (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body') 
  [0]).appendChild(d);
 })();

I’m getting the “Loading Discussion…” message but nothing further. I’ve tried tracing the issue and this is what I think is happening.

On Sidekiq the job Jobs::RetrieveTopic fails with Jobs::HandledExceptionWrapper: Wrapped FrozenError: can't modify frozen String.

I’ve traced it back in the code to line 192 in TopicEmbed.absolutize_url method:

prefix = "#{uri.scheme}://#{uri.host}"
prefix << ":#{uri.port}" if uri.port != 80 && uri.port != 443

Since my port is 5000 (not 80, or 443) the code attempts to concatenate the port to the prefix string and a FrozenError is raised. The RetrieveTopic job has the pragma comment # frozen_string_literal: true. I’ve actually tried removing it as an experiment but the problem persists, so I’m not sure if all string literals are frozen by default in Discourse.

Any tips on how to make this work locally? Also, if string literals are indeed supposed to be frozen, is this a bug?

Discourse does not support running on non-standard ports.

1 Like