Unsure what this error means
Not sure what this error means at all. I have a rather large set of columns that I need to get, but I can't tell if this is an inconsistency in my column reads, or whether Crystal is trying to handle a Nil value or something, if anyone could help that would be great.
Error:
Nil assertion failed (Exception)
0x101ba8b45: *CallStack::unwind:Array(Pointer(Void)) at ??
0x101ba8ae1: *CallStack#initialize:Array(Pointer(Void)) at ??
0x101ba8ab8: *CallStack::new:CallStack at ??
0x101b91f71: *raise<Exception>:NoReturn at ??
0x101b91f51: *raise<String>:NoReturn at ??
0x101bdff33: *Nil#not_nil!:NoReturn at ??
0x101c58744: *MySql::ResultSet#read:(Bool | Float32 | Float64 | Int16 | Int32 | Int64 | Int8 | Slice(UInt8) | String | Time | Nil) at ??
0x101c592b2: *DB::ResultSet+@DB::ResultSet#read<Int32:Class>:Int32 at ??
0x101c71210: *Campaign#send_emails<String, String, NamedTuple(campaign_id: Int32, value: String, query: String, count: Int32, id_list: Int32, subject: String, html: String, txt: String, from: String, mirror: String, unsubscribe: String), String>:(DB::ExecResult | Nil) at ??
0x101c70802: *Campaign#update_campaign_status<String, String, NamedTuple(campaign_id: Int32, value: String, query: String, count: Int32, id_list: Int32, subject:
String, html: String, txt: String, from: String, mirror: String, unsubscribe: String), String>:(DB::ExecResult | Nil) at ??
0x101c6efc0: *Campaign#get_segment_from_db<NamedTuple(campaign_id: Int32, value: String, query: String, count: Int32, id_list: Int32, subject: String, html: Strin
g, txt: String, from: String, mirror: String, unsubscribe: String)>:(DB::ExecResult | Nil) at ??
0x101c6a048: *Campaign#prepare_campaign:(DB::ExecResult | Nil) at ??
0x101c69e83: *Campaign#initialize<Int32, Int32, Int32, Int8, String, Int32, String, String, Int32, Bool, Redis, String>:(DB::ExecResult | Nil) at ??
0x101c69d4f: *Campaign::new:scheduler_id:account_id:campaign_id:campaign_percentage:host:sender_id:user:password:port:debug:redis_conn:campaign_lock_file<Int32, I
nt32, Int32, Int8, String, Int32, String, String, Int32, Bool, Redis, String>:Campaign at ??
0x101be5e7b: *Scheduler#build_campaigns<Array(NamedTuple(scheduler_id: Int32, campaign_id: Int32, account_id: Int32, percentage: Int8, sender_id: Int32))>:Nil at
??
0x101be4ee5: *Scheduler#get_schedules_from_db:Nil at ??
0x101be3fc1: *Scheduler#initialize<Bool>:Nil at ??
0x101be3ef7: *Scheduler::new<Bool>:Scheduler at ??
0x101b917d8: __crystal_main at ??
0x101ba3118: main at ??
Hi, a code sample would be needed to see what's really going on here. A stack trace doesn't tell us enough on its own.
Error Once Again:
Nil assertion failed (Exception)
0x10f35e9e5: *CallStack::unwind:Array(Pointer(Void)) at ??
0x10f35e981: *CallStack#initialize:Array(Pointer(Void)) at ??
0x10f35e958: *CallStack::new:CallStack at ??
0x10f347e01: *raise<Exception>:NoReturn at ??
0x10f347de1: *raise<String>:NoReturn at ??
0x10f395d63: *Nil#not_nil!:NoReturn at ??
0x10f426d9e: *Campaign#send_emails<String, String, NamedTuple(campaign_id: Int32, value: String, query: String, count: Int32, id_list: Int32, subject: String, html: String, txt: String, from: String, mirror: String, unsubscribe: String), S
tring>:Nil at ??
0x10f4266af: *Campaign#update_campaign_status<String, String, NamedTuple(campaign_id: Int32, value: String, query: String, count: Int32, id_list: Int32, subject: String, html: String, txt: String, from: String, mirror: String, unsubscribe:
String), String>:Nil at ??
0x10f424e88: *Campaign#get_segment_from_db<NamedTuple(campaign_id: Int32, value: String, query: String, count: Int32, id_list: Int32, subject: String, html: String, txt: String, from: String, mirror: String, unsubscribe: String)>:Nil at ??
0x10f41ff31: *Campaign#prepare_campaign:Nil at ??
0x10f41fd7b: *Campaign#initialize<Int32, Int32, Int32, Int8, String, Int32, String, String, Int32, Bool, Redis, String>:Nil at ??
0x10f41fcd4:*Campaign::new:scheduler_id:account_id:campaign_id:campaign_percentage:host:sender_id:user:password:port:debug:redis_conn:campaign_lock_file<Int32, Int32, Int32, Int8, String, Int32, String, String, Int32, Bool, Redis, String>:Campaign at ??
0x10f39bcab: *Scheduler#build_campaigns<Array(NamedTuple(scheduler_id: Int32, campaign_id: Int32, account_id: Int32, percentage: Int8, sender_id: Int32))>:Nil at ??
0x10f39ad15: *Scheduler#get_schedules_from_db:Nil at ??
0x10f399df1: *Scheduler#initialize<Bool>:Nil at ??
0x10f399d27: *Scheduler::new<Bool>:Scheduler at ??
0x10f347668: __crystal_main at ??
0x10f358fb8: main at ??
DB Function:
def db_proc(query_string : String, alternate_db=nil, exec=:single_result)
if @debug == true
puts "Alternate DB to Use: ".colorize(:yellow).to_s + alternate_db.colorize(:blue).to_s unless alternate_db.nil?
puts "No alternate DB provided, using default #{@scheduler_db[:database]}".colorize(:yellow) if alternate_db.nil?
puts query_string.colorize(:yellow)
end
case exec
when :single_result
DB.open "#{@scheduler_db[:type]}://#{@scheduler_db[:username]}:#{@scheduler_db[:password]}@#{@scheduler_db[:ip]}:#{@scheduler_db[:port]}/#{alternate_db.nil? ? @scheduler_db[:database] : alternate_db}" do |db|
db.query query_string do |results|
# Check if multiple rows or just one result
loop do
yield(results)
break unless results.move_next
end
end
end
when :multi_result
DB.open "#{@scheduler_db[:type]}://#{@scheduler_db[:username]}:#{@scheduler_db[:password]}@#{@scheduler_db[:ip]}:#{@scheduler_db[:port]}/#{alternate_db.nil? ? @scheduler_db[:database] : alternate_db}" do |db|
db.query_each query_string do |result|
yield(result)
end
end
else :execute
DB.open "#{@scheduler_db[:type]}://#{@scheduler_db[:username]}:#{@scheduler_db[:password]}@#{@scheduler_db[:ip]}:#{@scheduler_db[:port]}/#{alternate_db.nil? ? @scheduler_db[:database] : alternate_db}" do |db|
db.exec query_string
end
end
end
Code to get results:
db_proc(segment_query, alternate_db, exec: :multi_result) do |result|
# Get results from segment query
id, email, domain, firstname, lastname, gender, civility, birthday, country, state, city, postalcode, address, address_two, phone, phone_fix, perso_field1, perso_field2, perso_field3, perso_field4, perso_field5, perso_field6, perso_field7, perso_field8, perso_field9, perso_field10, date_join, datetime_join, date_status, status \
= result.read(Int32, String, String, String, String, String, String, Time, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, Time, Time, Time, String)
if !targets_info.not_nil!
targets_info = [{target_id: id, email_address: email.blank? ? "" : email, domain: domain.blank? ? "" : domain, firstname: firstname.blank? ? "" : firstname, lastname: lastname.blank? ? "" : lastname, gender: gender.blank? ? "NA" : gender, civility: civility.blank? ? "" : civility, birthday: birthday, country: country.blank? ? "" : country, state: state.blank? ? "" : state, city: city.blank? ? "" : city, postalcode: postalcode.blank? ? "" : postalcode, address: address.blank? ? "" : address, address_two: address_two.blank? ? "" : address_two, phone: phone.blank? ? "" : phone, phone_fix: phone_fix.blank? ? "" : phone_fix, date_join: date_join, datetime_join: datetime_join, date_status: date_status, status: status}]
elsif targets_info.not_nil!
targets_info += [{target_id: id, email_address: email.blank? ? "" : email, domain: domain.blank? ? "" : domain, firstname: firstname.blank? ? "" : firstname, lastname: lastname.blank? ? "" : lastname, gender: gender.blank? ? "NA" : gender, civility: civility.blank? ? "" : civility, birthday: birthday, country: country.blank? ? "" : country, state: state.blank? ? "" : state, city: city.blank? ? "" : city, postalcode: postalcode.blank? ? "" : postalcode, address: address.blank? ? "" : address, address_two: address_two.blank? ? "" : address_two, phone: phone.blank? ? "" : phone, phone_fix: phone_fix.blank? ? "" : phone_fix, date_join: date_join, datetime_join: datetime_join, date_status: date_status, status: status}]
else
puts "Sorry there was an issue with the target_info..."
end
end
@RX14
Probably some of those many columns has a nil. And result.read(Int32, String, String, String ... states that non of the columns are nillable.
You should be able to use result.read(Int32, String?, String, String?... to state which ones are nillable.
But, other than that, you can use http://crystal-lang.github.io/crystal-db/api/0.4.2/DB.html#mapping%28properties%2Cstrict%3Dtrue%29-macro in this case to simplify a bit the code.
The line !targets_info.not_nil! will also fail. If targets_info is nil, targets_info.not_nil! will raise. You can do if !targets or if targets.nil?.
Instead of targets_info += [ is better to targets_info << so you don't create intermediate arrays. Simplifying the load of the GC.
query_all will return an array with all the rows, you you don't even need to collect row by row.