Problem z sitemap.xml na Heroku


#1

Mam aplikację Ruby on Rails i chcę zautomatyzować tworzenie pliku sitemap.xml (w katalogu public). Używam do tego gemu sitemap_generator, ale gdy chcę z palca wejść na plik z sitemapą https://example.com/sitemap.xml to na produkcji w Heroku leci błąd 500. Dodam, że na produkcji lokalnie wszystko działa poprawnie i bez problemu mogę zobaczyć zawartość tego pliku.

sitemap.rb

# Set the host name for URL creation
SitemapGenerator::Sitemap.default_host = "https://example.com"

SitemapGenerator::Sitemap.namer = SitemapGenerator::SimpleNamer.new(:sitemap, :extension => '.xml')

SitemapGenerator::Sitemap.create do

  Category.find_each do |cat|
    add category_path(cat), priority: 0.8, changefreq: 'daily', lastmod: cat.updated_at
  end

  Job.where(status: true).find_each do |job|
    add job_path(job), priority: 0.6, lastmod: job.updated_at
  end

end

Do obsługi błędów mam taki kontroler:

errors_controller.rb

class ErrorsController < ApplicationController

  def not_found
    render status: 404
  end

  def unprocessable_entity
    render status: 422
  end

  def internal_server_error
    render status: 500
  end

end

Mam widoki dla wszystkich rodzajów błędów, które zdefiniowane są w kontrolerze, ale poniższe logi Heroku wskazują jakby problem leżał w widokach:

I, [2019-10-16T11:57:53 #4]  INFO -- : Processing by ErrorsController#not_found as XML
I, [2019-10-16T11:57:53 #4]  INFO -- : Completed 500 Internal Server Error in 2ms (ActiveRecord: 0.0ms)
2019-10-16T11:57:53 app[web.1]: Error during failsafe response: Missing template errors/not_found, application/not_found with {:locale=>[:en], :formats=>[:xml], :variants=>[], :handlers=>[:raw, :erb, :html, :builder, :ruby, :coffee, :jbuilder, :haml]}. Searched in:
2019-10-16T11:57:53 app[web.1]: * "/app/app/views"

Polecenie heroku run rails sitemap:refresh:no_ping tworzy sitemapę z linkami wszystkimi jakie potrzebuję https://mywebsite.com/sitemap.xml - ale kiedy chcę odpalić plik sitemapy lub sprawdzić ją w narzędziach Google to dostaję błąd 500. Podejrzewam, że jest to związane z obsługą błędów, bo https://mywebsite.com/sitemap (bez .xml) wyświetla widok z błędem 404. Z kolei z rozszerzeniem .xml błąd 500 (ale nie z moich widoków).

Zastanawia mnie to, dlaczego na localu wszystko działa poprawnie zarówno w środowisko dev jak i prod, a na Heroku nie.

Może ma ktoś pomysł jak poradzić sobie z tym problemem?


#2

Po pierwsze - gdzie ten gem tworzy ci plik sitemap.xml?

Po drugie - twoj error controller nadal probuje zwrocic html. Powinienes uzyc parametru plain albo head zaleznie od tego jaki chcesz efekt uzyskac. Polecam lekture https://guides.rubyonrails.org/layouts_and_rendering.html#using-render jak i pozostalych guide’ow z tej strony.


#3

Po pierwsze - gdzie ten gem tworzy ci plik sitemap.xml?

Na samym początku napisałem, że w katalogu public.


#4

Na stronie sitemap_generatora na githubie: https://github.com/kjvarga/sitemap_generator jest jak wół napisane: " * Supports read-only filesystems like Heroku via uploading to a remote host like Amazon S3"

Z Twojego opisu wynika, że sitemap-ę generujesz na heroku już po zbudowaniu assetów lokalnie, co w/g dokumentacji Twojego gema nie zadziała z Heroku. Podejrzewam, że używasz domyślnego: SitemapGenerator::FileAdapter’a. Polecam lekturę: https://github.com/kjvarga/sitemap_generator#upload-sitemaps-to-a-remote-host-using-adapters

Ewentualnie możesz kombinować z wpięciem generowania sitemap’y w proces prekompilacji assets-ów, ale to już bardziej zaawansowany temat.


#5

Sitemapę zapisz na S3 i dodaj kontroler mniej więcej taki:

require "open-uri"

class SitemapController < ApplicationController
  def show
    send_data open("http://my-host.s3.amazonaws.com/sitemap.xml.gz").read,
      content_type: "application/x-gzip",
      disposition: :inline
  end
end