Make sure we always throw ProtocolException(INVALID_DATA) in Ruby
diff --git a/lib/rb/ext/struct.c b/lib/rb/ext/struct.c
index c36c161..b61b995 100644
--- a/lib/rb/ext/struct.c
+++ b/lib/rb/ext/struct.c
@@ -20,6 +20,7 @@
#include "struct.h"
#include "constants.h"
#include "macros.h"
+#include "protocol.h"
#include "strlcpy.h"
VALUE thrift_union_class;
@@ -656,7 +657,7 @@
field_type = FIX2INT(field_type_value);
if (field_type != TTYPE_STOP) {
- rb_raise(rb_eRuntimeError, "too many fields in union!");
+ rb_exc_raise(get_protocol_exception(INT2FIX(PROTOERR_INVALID_DATA), rb_str_new2("too many fields in union!")));
}
// read struct end
@@ -684,7 +685,7 @@
VALUE field_info = rb_hash_aref(struct_fields, field_id);
if(NIL_P(field_info)) {
- rb_raise(rb_eRuntimeError, "set_field is not valid for this union!");
+ rb_exc_raise(get_protocol_exception(INT2FIX(PROTOERR_INVALID_DATA), rb_str_new2("set_field is not valid for this union!")));
}
VALUE ttype_value = rb_hash_aref(field_info, type_sym);
diff --git a/lib/rb/lib/thrift/union.rb b/lib/rb/lib/thrift/union.rb
index 88c4285..822ab2f 100644
--- a/lib/rb/lib/thrift/union.rb
+++ b/lib/rb/lib/thrift/union.rb
@@ -60,7 +60,9 @@
iprot.read_field_end
fname, ftype, fid = iprot.read_field_begin
- raise "Too many fields for union" unless (ftype == Types::STOP)
+ unless (ftype == Types::STOP)
+ raise ProtocolException.new(ProtocolException::INVALID_DATA, "Too many fields for union")
+ end
iprot.read_struct_end
validate
@@ -73,7 +75,9 @@
fid = self.name_to_id(@setfield.to_s)
field_info = struct_fields[fid]
- raise "set_field is not valid for this union!" unless field_info
+ unless field_info
+ raise ProtocolException.new(ProtocolException::INVALID_DATA, "set_field is not valid for this union!")
+ end
type = field_info[:type]
if is_container? type
diff --git a/lib/rb/spec/union_spec.rb b/lib/rb/spec/union_spec.rb
index 7bf4ca0..f38093d 100644
--- a/lib/rb/spec/union_spec.rb
+++ b/lib/rb/spec/union_spec.rb
@@ -51,7 +51,9 @@
it "should raise for wrong set field when hash initialized and type checking is off" do
Thrift.type_checking = false
union = SpecNamespace::My_union.new({incorrect_field: :incorrect})
- expect { Thrift::Serializer.new.serialize(union) }.to raise_error(RuntimeError, "set_field is not valid for this union!")
+ expect { Thrift::Serializer.new.serialize(union) }.to raise_error(Thrift::ProtocolException, "set_field is not valid for this union!") { |error|
+ expect(error.type).to eq(Thrift::ProtocolException::INVALID_DATA)
+ }
end
it "should not be equal to nil" do
@@ -148,7 +150,9 @@
it "should raise when validating unset union" do
union = SpecNamespace::My_union.new
- expect { union.validate }.to raise_error(StandardError, "Union fields are not set.")
+ expect { union.validate }.to raise_error(Thrift::ProtocolException, "Union fields are not set.") { |error|
+ expect(error.type).to eq(Thrift::ProtocolException::INVALID_DATA)
+ }
other_union = SpecNamespace::My_union.new(:integer32, 1)
expect { other_union.validate }.not_to raise_error
@@ -157,7 +161,9 @@
it "should validate an enum field properly" do
union = SpecNamespace::TestUnion.new(:enum_field, 3)
expect(union.get_set_field).to eq(:enum_field)
- expect { union.validate }.to raise_error(Thrift::ProtocolException, "Invalid value of field enum_field!")
+ expect { union.validate }.to raise_error(Thrift::ProtocolException, "Invalid value of field enum_field!") { |error|
+ expect(error.type).to eq(Thrift::ProtocolException::INVALID_DATA)
+ }
other_union = SpecNamespace::TestUnion.new(:enum_field, 1)
expect { other_union.validate }.not_to raise_error