I have an app where you submit a link and some info is extracted from it using "net/http" and Nokogiri. The way it works is that a user submits an URL and before the post is saved, the info is extracted from the URL and added to different properties of the model: title, description, etc...
Sometimes, when there is a problem with the link, the before_save fails, like for example when the SSL certificate verification fails like this:
OpenSSL::SSL::SSLError (SSL_connect returned=1 errno=0 state=error: certificate verify failed (unable to get local issuer certificate))
How do I make sure this or any error is presented to the user so that they know what's going on?
I am using Rails 7 and Hotwire, currently an error like this fails silently. I can see it in the console but nothing is shown in the frontend.
Here is my create action:
def create
notice = "Company created."
@company = Company.new(company_params)
@company.user_id = current_user.id
if @company.save
respond_to do |format|
format.html { redirect_to company_path(@company), notice: notice }
format.turbo_stream { flash.now[:notice] = notice }
end
else
render :new, status: :unprocessable_entity
end
end
I tried also adding a notice for "else", like the following but still nothing is shown when the saving fails.
def create
@company = Company.new(company_params)
@company.user_id = current_user.id
if @company.save
notice = "Company created."
respond_to do |format|
format.html { redirect_to company_path(@company), notice: notice }
format.turbo_stream { flash.now[:notice] = notice }
end
else
notice = "Company could not be created!"
respond_to do |format|
format.html { render :new, status: :unprocessable_entity }
format.turbo_stream { flash.now[:notice] = notice }
end
end
end
To parse the url I use:
require "net/http"
noko = Nokogiri::HTML(Net::HTTP.get(URI("https://sample-url.com")))
Then for example to extract the title I do:
noko.title
I have a before_save in the model that assigns the title like:
self.title = noko.title
Everything works as expected, except when the before_save fails, like in the example above. Do you have any suggestions on either:
- how to make sure those errors show in the front?
- how would you implement something similar if you wouldn't use the before_save option?
- Any other suggestion is greatly appreciated!
Thanks a lot in advance!
I could solve this problem with 2 different approach. First adding errors in before_save method or raise an exception.
First approach prevents record from saving. It adds errors to the object which can be access by
object.errors.details. Ifobject.savereturn false then in the else block you can show the errors to user.Second approach is raising exceptions instead of handling errors more silently. You can rescue this exceptions in your controller and show this errors to the user.
I would suggest the first approach because it is easy to implement, raising StandardError not a best thing to do here. I would suggest you to define custom exception classes for your application if you are going to choose the second way.
Edit: I suggested fastest implementation based on your question. If you are looking for more clean solution then you can create a service class and move all the logic to the service which includes creating a company and extracting data. Above 2 approach still viable in this service class so pick whatever you like.
Links that can help you:
acticle about handling exceptions
documentation about active model errors.
acticle about service object approach.