From 0df1e398eb6022602b2909acdfe06c668ae6a8a2 Mon Sep 17 00:00:00 2001 From: Anders Carling Date: Fri, 20 Nov 2015 21:55:13 +0100 Subject: Raise NoMethodError for unknown fields More informative and more ruby-like --- ruby/ext/google/protobuf_c/message.c | 2 +- .../src/main/java/com/google/protobuf/jruby/RubyMessage.java | 12 ++++++++++++ ruby/tests/basic.rb | 12 ++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) (limited to 'ruby') diff --git a/ruby/ext/google/protobuf_c/message.c b/ruby/ext/google/protobuf_c/message.c index ebe2f1ab4..1f079f1d6 100644 --- a/ruby/ext/google/protobuf_c/message.c +++ b/ruby/ext/google/protobuf_c/message.c @@ -166,7 +166,7 @@ VALUE Message_method_missing(int argc, VALUE* argv, VALUE _self) { name, name_len); if (f == NULL) { - rb_raise(rb_eArgError, "Unknown field"); + return rb_call_super(argc, argv); } if (setter) { diff --git a/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java b/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java index 547ab22cb..e313518de 100644 --- a/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java +++ b/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java @@ -217,6 +217,9 @@ public class RubyMessage extends RubyObject { RubyDescriptor rubyDescriptor = (RubyDescriptor) getDescriptor(context, metaClass); IRubyObject oneofDescriptor = rubyDescriptor.lookupOneof(context, args[0]); if (oneofDescriptor.isNil()) { + if (!hasField(args[0])) { + throw context.runtime.newNoMethodError("undefined method `" + args[0].toString() + "' for " + metaClass.toString(), args[0].asJavaString(), metaClass); + } return index(context, args[0]); } RubyOneofDescriptor rubyOneofDescriptor = (RubyOneofDescriptor) oneofDescriptor; @@ -233,6 +236,10 @@ public class RubyMessage extends RubyObject { if (field.end_with_p(context, equalSign).isTrue()) { field.chomp_bang(context, equalSign); } + + if (!hasField(field)) { + throw context.runtime.newNoMethodError("undefined method `" + args[0].asJavaString() + "' for " + metaClass.toString(), args[0].asJavaString(), metaClass); + } return indexSet(context, field, args[1]); } } @@ -435,6 +442,11 @@ public class RubyMessage extends RubyObject { return ret; } + private boolean hasField(IRubyObject fieldName) { + String nameStr = fieldName.asJavaString(); + return this.descriptor.findFieldByName(Utils.escapeIdentifier(nameStr)) != null; + } + private void checkRepeatedFieldType(ThreadContext context, IRubyObject value, Descriptors.FieldDescriptor fieldDescriptor) { Ruby runtime = context.runtime; diff --git a/ruby/tests/basic.rb b/ruby/tests/basic.rb index 40c200786..815abc46a 100644 --- a/ruby/tests/basic.rb +++ b/ruby/tests/basic.rb @@ -191,6 +191,18 @@ module BasicTest assert m1.hash != m2.hash end + def test_unknown_field_errors + e = assert_raise NoMethodError do + TestMessage.new.hello + end + assert_match(/hello/, e.message) + + e = assert_raise NoMethodError do + TestMessage.new.hello = "world" + end + assert_match(/hello/, e.message) + end + def test_type_errors m = TestMessage.new assert_raise TypeError do -- cgit v1.2.3