From 8c6e0a3591ab93d78ab6bd8e821b2f45d0d60a5d Mon Sep 17 00:00:00 2001 From: Kyle Banker Date: Wed, 20 Jan 2010 12:11:58 -0500 Subject: [PATCH] Raise better error message when trying to serialize TimeWithZone --- ext/cbson/cbson.c | 9 +++++---- lib/mongo/util/bson_ruby.rb | 10 ++++++++-- test/test_bson.rb | 14 +++++++++++--- 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/ext/cbson/cbson.c b/ext/cbson/cbson.c index 7b468d4..c3da32b 100644 --- a/ext/cbson/cbson.c +++ b/ext/cbson/cbson.c @@ -369,13 +369,13 @@ static int write_element_allow_id(VALUE key, VALUE value, VALUE extra, int allow SAFE_WRITE_AT_POS(buffer, length_location, (const char*)&obj_length, 4); break; } - if (strcmp(cls, "DateTime") == 0 || strcmp(cls, "Date") == 0) { + if (strcmp(cls, "DateTime") == 0 || strcmp(cls, "Date") == 0 || strcmp(cls, "ActiveSupport::TimeWithZone") == 0) { buffer_free(buffer); - rb_raise(InvalidDocument, "Trying to use Date or DateTime; the driver currently supports Time objects only.", + rb_raise(InvalidDocument, "Trying to serialize and instance of Date, DateTime, or TimeWithZone; the MongoDB Ruby driver currently supports Time objects only.", TYPE(value)); } buffer_free(buffer); - rb_raise(InvalidDocument, "Unsupported type for BSON (%d)", TYPE(value)); + rb_raise(InvalidDocument, "Cannot serialize an object of class %s into BSON.", cls); break; } case T_DATA: @@ -428,8 +428,9 @@ static int write_element_allow_id(VALUE key, VALUE value, VALUE extra, int allow } default: { + const char* cls = rb_class2name(RBASIC(value)->klass); buffer_free(buffer); - rb_raise(InvalidDocument, "Unsupported type for BSON (%d)", TYPE(value)); + rb_raise(InvalidDocument, "Cannot serialize an object of class %s into BSON.", cls); break; } } diff --git a/lib/mongo/util/bson_ruby.rb b/lib/mongo/util/bson_ruby.rb index b2097f0..25e9de9 100644 --- a/lib/mongo/util/bson_ruby.rb +++ b/lib/mongo/util/bson_ruby.rb @@ -554,9 +554,15 @@ class BSON_RUBY when Symbol SYMBOL when Date, DateTime - raise InvalidDocument, "Trying to use Date or DateTime; the driver currently supports Time objects only." + raise InvalidDocument, "Trying to serialize an instance of #{o.class}; " + + "the MongoDB Ruby driver currently supports Time objects only." else - raise InvalidDocument, "Unknown type of object: #{o.class.name}" + if defined?(ActiveSupport::TimeWithZone) && o.is_a?(ActiveSupport::TimeWithZone) + raise InvalidDocument, "Trying to serialize an instance of ActiveSupport::TimeWithZone; " + + "the MongoDB Ruby driver currently supports Time objects only." + else + raise InvalidDocument, "Unknown type of object: #{o.class.name}" + end end end diff --git a/test/test_bson.rb b/test/test_bson.rb index f62e6f9..a0052a1 100644 --- a/test/test_bson.rb +++ b/test/test_bson.rb @@ -1,6 +1,13 @@ # encoding:utf-8 require 'test/test_helper' +# Need to simulating this class +# without actually loading it. +module ActiveSupport + class TimeWithZone + end +end + class BSONTest < Test::Unit::TestCase include Mongo @@ -181,15 +188,16 @@ class BSONTest < Test::Unit::TestCase end end - def test_exeption_on_using_date - [DateTime.now, Date.today].each do |invalid_date| + def test_exeption_on_using_unsupported_date_class + [DateTime.now, Date.today, ActiveSupport::TimeWithZone.new].each do |invalid_date| doc = {:date => invalid_date} begin bson = BSON.serialize(doc) rescue => e ensure + puts e.message assert_equal InvalidDocument, e.class - assert_match /Time/, e.message + assert_match /Time objects only/, e.message end end end