Getting a list of existing Rails Error classes for re-use/inheritance - ruby-on-rails-3

Often I need to throw a custom(ized) error. Like when a resource cannot be found due to a mismatch in parameters or so.
I prefer to throw existing errors or, throw an error that is inherited from an existing error. That way, I don't introduce Error classes that were already defined and could have been used perfectly (DRY). But it also allows to keep wording and style the same, by inheriting and simply changing a word or two to clarify the difference with the original Error.
For example:
Foo.new
Foo.some_external_id = nil
Foo.fetch_external_resource
# => InvalidOptions: Calling Foo#fetch_external_resource with nil is invalid
I am quite sure such errors are already defined. In fact, after reading trough many lines of code, I found my MongoID driver has Mongoid::Errors::InvalidOptions: Calling Document#find with nil is invalid.
Is there a list of available Error classes in Ruby Core and Ruby on Rails? Is there a way to get such a list for your current project?
Is it smart at all to re-use and/or inherit existing errors, or should I maintain my own, custom set instead?

While this list may change, and it's best to still use Ryan's solution, the list for Rails 4 (limited to Rails classes and not other gems):
AbstractController::ActionNotFound
AbstractController::DoubleRenderError
AbstractController::Error
AbstractController::Helpers::ClassMethods::MissingHelperError
ActionController::ActionControllerError
ActionController::BadRequest
ActionController::InvalidAuthenticityToken
ActionController::MethodNotAllowed
ActionController::MissingFile
ActionController::NotImplemented
ActionController::ParameterMissing
ActionController::RedirectBackError
ActionController::RenderError
ActionController::RoutingError
ActionController::SessionOverflowError
ActionController::UnknownController
ActionController::UnknownFormat
ActionController::UnknownHttpMethod
ActionController::UnpermittedParameters
ActionController::UrlGenerationError
ActionDispatch::Cookies::CookieOverflow
ActionDispatch::IllegalStateError
ActionDispatch::Journey::Router::RoutingError
ActionDispatch::ParamsParser::ParseError
ActionDispatch::RemoteIp::IpSpoofAttackError
ActionDispatch::Session::SessionRestoreError
ActionView::Helpers::NumberHelper::InvalidNumberError
ActiveModel::ForbiddenAttributesError
ActiveModel::MissingAttributeError
ActiveRecord::ActiveRecordError
ActiveRecord::AdapterNotFound
ActiveRecord::AdapterNotSpecified
ActiveRecord::AssociationTypeMismatch
ActiveRecord::AttributeAssignmentError
ActiveRecord::ConfigurationError
ActiveRecord::ConnectionNotEstablished
ActiveRecord::ConnectionTimeoutError
ActiveRecord::DangerousAttributeError
ActiveRecord::DeleteRestrictionError
ActiveRecord::DuplicateMigrationNameError
ActiveRecord::DuplicateMigrationVersionError
ActiveRecord::EagerLoadPolymorphicError
ActiveRecord::HasAndBelongsToManyAssociationForeignKeyNeeded
ActiveRecord::HasManyThroughAssociationNotFoundError
ActiveRecord::HasManyThroughAssociationPointlessSourceTypeError
ActiveRecord::HasManyThroughAssociationPolymorphicSourceError
ActiveRecord::HasManyThroughAssociationPolymorphicThroughError
ActiveRecord::HasManyThroughCantAssociateNewRecords
ActiveRecord::HasManyThroughCantAssociateThroughHasOneOrManyReflection
ActiveRecord::HasManyThroughCantDissociateNewRecords
ActiveRecord::HasManyThroughNestedAssociationsAreReadonly
ActiveRecord::HasManyThroughSourceAssociationNotFoundError
ActiveRecord::HasOneThroughCantAssociateThroughCollection
ActiveRecord::IllegalMigrationNameError
ActiveRecord::ImmutableRelation
ActiveRecord::InvalidForeignKey
ActiveRecord::InverseOfAssociationNotFoundError
ActiveRecord::IrreversibleMigration
ActiveRecord::MultiparameterAssignmentErrors
ActiveRecord::NestedAttributes::TooManyRecords
ActiveRecord::PendingMigrationError
ActiveRecord::PreparedStatementInvalid
ActiveRecord::ReadOnlyAssociation
ActiveRecord::ReadOnlyRecord
ActiveRecord::RecordInvalid
ActiveRecord::RecordNotDestroyed
ActiveRecord::RecordNotFound
ActiveRecord::RecordNotSaved
ActiveRecord::RecordNotUnique
ActiveRecord::Rollback
ActiveRecord::SerializationTypeMismatch
ActiveRecord::StaleObjectError
ActiveRecord::StatementInvalid
ActiveRecord::SubclassNotFound
ActiveRecord::Tasks::DatabaseAlreadyExists
ActiveRecord::Tasks::DatabaseNotSupported
ActiveRecord::ThrowResult
ActiveRecord::TransactionIsolationError
ActiveRecord::Transactions::TransactionError
ActiveRecord::UnknownAttributeError
ActiveRecord::UnknownMigrationVersionError
ActiveRecord::UnknownPrimaryKey
ActiveRecord::WrappedDatabaseException
ActiveSupport::JSON::Encoding::CircularReferenceError
ActiveSupport::MessageVerifier::InvalidSignature
ActiveSupport::SafeBuffer::SafeConcatError
ActiveSupport::XMLConverter::DisallowedType

There's a mostly adequate solution here: http://www.ruby-forum.com/topic/158088
Since this question is unanswered, yet coming up at the top of Google search results, I decided to wrap Frederick Cheung's solution up in a rake task and post it here.
Drop the following in lib/tasks/exceptions.rake
namespace :exceptions do
task :list => :environment do
exceptions = []
ObjectSpace.each_object(Class) do |k|
exceptions << k if k.ancestors.include?(Exception)
end
puts exceptions.sort { |a,b| a.to_s <=> b.to_s }.join("\n")
end
end
Run it with:
bundle exec rake exceptions:list
If you're still on Rails 2, or not using Bundler, leave off the bundle exec
This list is probably adequate, but not exhaustive. For example, ActiveResource defines several exceptions such as ActiveResource::ConnectionError and ActiveResource::TimeoutError that are not appearing when I run this task. Maybe someone else can enlighten me as to why.

A shorter option is available in Rails thanks to ActiveSupport:
puts Exception.descendants.sort_by(&:name)
You can also check out the source to see how they handle it.

Related

Using Optaplanner for VRPPD

I am trying to run the example "optaplanner-mixedvrp-experiment" developed by Geoffrey De Smet and when I run it it throws me the following error:
Caused by: java.lang.IllegalStateException: The entity (MY) has a
variable (previousStandstill) with value (MUNO) which has a
sourceVariableName variable (nextVisit) with a value (WERBOMONT) which
is not null. Verify the consistency of your input problem for that
sourceVariableName variable.
I have not made any change, I have only cloned and executed it, I import and solve it and it throws me this error.
Do you know what could be happening?
I am applying it in the development of a variant of VRP with multiple deliveries and collections, but it throws me the same error. I have activated the FULL_ASSERT mode and nextVisit, previousStandstill, visitIndex are always null
It's been a long time since I looked at that code, so it's using an old version of optaplanner. Our goal is still to clean it up and offer an out of the box example for VRPPD (and probably remove some boilerplate along the way, using the upcoming #CollectionPlanningVariabe etc). That being said, we have multiple users&customers who used that optaplanner-mixedvrp-experiment to successfully build VRPPD implementations.
Which dataset did you try?
FWIW, that IllegalStateException says that when A.previous = B, the B.next is not A. So either the dataset importer didn't import it correctly - before calling solve() - especially if it fails before the first CH step in FULL_ASSERT. Or one of the custom moves corrupted the model.

Getting "Can not convert the given object to query." with ColdFusion ORM

This is happening intermittently (usually at start up). I get the above error message when executing the following code.
var arr = ORMExecuteQuery( "FROM priority WHERE active = 1 ORDER BY sortOrder" );
var qry = entityToQuery( arr );
The first line executes fine, but the second line blows up. The solution is to run ormreload();
The problem keeps coming up in an unpredictable way though. Even when no changes have been made to the beans or gateways that are using ORM. Completely unpredictable and impossible to replicate on purpose. Is there something else that can mess with the hibernate mappings that could cause this type of problem.
Other info that may be pertinent:
This is a MURA plugin based on a recent version of FW/1.
ormreload() is a persistent fix (until it fails again)
My current solution is to put ormreload() in the setupApplication() method of application.cfc
I just want to understand better what could be causing this problem.

delayed_job - NameError - uninitilized constant

I have this custom job which is located in /lib/jobs/MessageNotificationJob.rb
class MessageNotificationJob < Struct.new(:user_id, :message_id)
def perform
#user = User.find(user_id)
#message = Message.find(message_id)
if !message.reciever_open
MessagesMailer.message_notification(#user, #message ).deliver
end
end
end
I call it from a method in the MessagesController with
Delayed::Job.enqueue(MessageNotificationJob.new(#user.id, #msg.id))
In my application.rb I have
config.autoload_paths += Dir["#{config.root}/lib/**/"]
But I get the error
NameError - uninitialized constant MessagesController::MessageNotificationJob:
How do I fix this? I've tried several variations, with this as the latest one as a solution to a similar question. I am missing something?
I haven't used the latest DelayedJob, but it looks an awful like the delayed job doesn't have the MessageNotificationJob class loaded when it runs. Try the following:
# file: config/initializers/custom.rb
require 'message_notification_job'
See also this wiki entry -- I think newer versions of DJ improved the error message (rather than silently failing), but the underlying cause is the same.

Rails 3.2.2 log files unordered, requests intertwined

I recollect getting log files that were nicely ordered, so that you could follow one request, then the next, and so on.
Now, the log files are, as my 4 year old says "all scroggled up", meaning that they are no longer separate, distinct chunks of text. Loggings from two requests get intertwined/mixed up.
For instance:
Started GET /foobar
...
Completed 200 OK in 2ms (Views: 0.4ms | ActiveRecord: 0.8ms)
Patient Load (wait, that's from another request that has nothing to do with foobar!)
[ blank space ]
Something else
This is maddening, because I can't tell what's happening within one single request.
This is running on Passenger.
I tried to search for the same answer but couldn't find any good info. I'm not sure if you should fix server or rails code.
If you want more info about the issue here is the commit that removed old way of logging https://github.com/rails/rails/commit/04ef93dae6d9cec616973c1110a33894ad4ba6ed
If you value production log readability over everything else you can use the
PassengerMaxInstancesPerApp 1
configuration. It might cause some scaling issues. Alternatively you could stuff something like this in application.rb:
process_log_filename = Rails.root + "log/#{Rails.env}-#{Process.pid}.log"
log_file = File.open(process_log_filename, 'a')
Rails.logger = ActiveSupport::BufferedLogger.new(log_file)
Yep!, they have made some changes in the ActiveSupport::BufferedLogger so it is not any more waiting until the request has ended to flush the logs:
http://news.ycombinator.com/item?id=4483390
https://github.com/rails/rails/commit/04ef93dae6d9cec616973c1110a33894ad4ba6ed
But they have added the ActiveSupport::TaggedLogging which is very funny and you can stamp every log with any kind of mark you want.
In your case could be good to stamp the logs with the request UUID like this:
# config/application.rb
config.log_tags = [:uuid]
Then even if the logs are messed up you still can follow which of them correspond to the request you are following up.
You can make more funny things with this feature to help you in your logs study:
How to log user_name in Rails?
http://zogovic.com/post/21138929607/running-time-in-rails-logs
Well, for me the TaggedLogging solution is a no go, I can live with some logs getting lost if the server crashes badly, but I want my logs to be perfectly ordered. So, following advice from the issue comments I'm applying this to my app:
# lib/sequential_logs.rb
module ActiveSupport
class BufferedLogger
def flush
#log_dest.flush
end
def respond_to?(method, include_private = false)
super
end
end
end
# config/initializers/sequential_logs.rb
require 'sequential_logs.rb'
Rails.logger.instance_variable_get(:#logger).instance_variable_get(:#log_dest).sync = false
As far as I can say this hasn't affected my app, it is still running and now my logs make sense again.
They should add some quasi-random reqid and write it in every line regarding one single request. This way you won't get confused.
I haven't used it, but I believe Lumberjack's unit_of_work method may be what you're looking for. You call:
Lumberjack.unit_of_work do
yield
end
And all logging done either in that block or in the yielded block are tagged with a unique ID.

Transactions in Datamapper & Rails (dm-rails)

I have two models: hotel and location. A location belongs to a hotel, a hotel has one location. I'm trying to create both in a single form, bear in mind that I can't use dm-nested for nested forms due to a dependency clash.
I have code that looks like:
if (#hotel.save && #location.save)
# process
else
# back to form with errors
end
Unfortunately, #hotel.save can fail and #location.save can complete (which confuses me because I didn't think the second condition would run in an AND block if the first one failed).
I'd like to wrap these in a transaction so I can rollback the Location save. I can't seem to find a way to do it online. I'm using dm-rails, rails 3 and a postgresql database. Thanks.
The usual way to wrap database operations in DataMapper is to do something like this:
#hotel.transaction do
#hotel.save
#location.save
end
Notice that #hotel is quite arbitrary there; it could as well be #location or even a model name like Hotel.
In my experience, this works best when you enable exceptions to be thrown. Then if #hotel.save fails, it will throw an exception, which will be caught by the transaction block, causing the transaction to be rolled back. The exception is, of course, reraised.