Merge pull request #101 from realm/sk-object-getters
Non-existent object getters shouldn't throw exceptions
This commit is contained in:
commit
0df214ad21
|
@ -33,12 +33,14 @@ JSValueRef ObjectGetProperty(JSContextRef ctx, JSObjectRef jsObject, JSStringRef
|
||||||
try {
|
try {
|
||||||
Object *obj = RJSGetInternal<Object *>(jsObject);
|
Object *obj = RJSGetInternal<Object *>(jsObject);
|
||||||
return obj->get_property_value<JSValueRef>(ctx, RJSStringForJSString(jsPropertyName));
|
return obj->get_property_value<JSValueRef>(ctx, RJSStringForJSString(jsPropertyName));
|
||||||
|
} catch (InvalidPropertyException &ex) {
|
||||||
|
// getters for nonexistent properties in JS should always return undefined
|
||||||
} catch (std::exception &ex) {
|
} catch (std::exception &ex) {
|
||||||
if (exception) {
|
if (exception) {
|
||||||
*exception = RJSMakeError(ctx, ex);
|
*exception = RJSMakeError(ctx, ex);
|
||||||
}
|
}
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ObjectSetProperty(JSContextRef ctx, JSObjectRef jsObject, JSStringRef jsPropertyName, JSValueRef value, JSValueRef* exception) {
|
bool ObjectSetProperty(JSContextRef ctx, JSObjectRef jsObject, JSStringRef jsPropertyName, JSValueRef value, JSValueRef* exception) {
|
||||||
|
|
|
@ -99,6 +99,28 @@ namespace realm {
|
||||||
static Mixed to_mixed(ContextType ctx, ValueType &val) { throw std::runtime_error("'Any' type is unsupported"); }
|
static Mixed to_mixed(ContextType ctx, ValueType &val) { throw std::runtime_error("'Any' type is unsupported"); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class InvalidPropertyException : public std::runtime_error
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
InvalidPropertyException(const std::string object_type, const std::string property_name, const std::string message) : std::runtime_error(message), object_type(object_type), property_name(property_name) {}
|
||||||
|
const std::string object_type;
|
||||||
|
const std::string property_name;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MissingPropertyValueException : public std::runtime_error
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MissingPropertyValueException(const std::string object_type, const std::string property_name, const std::string message) : std::runtime_error(message), object_type(object_type), property_name(property_name) {}
|
||||||
|
const std::string object_type;
|
||||||
|
const std::string property_name;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MutationOutsideTransactionException : public std::runtime_error
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MutationOutsideTransactionException(std::string message) : std::runtime_error(message) {}
|
||||||
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
// template method implementations
|
// template method implementations
|
||||||
//
|
//
|
||||||
|
@ -107,7 +129,8 @@ namespace realm {
|
||||||
{
|
{
|
||||||
const Property *prop = object_schema.property_for_name(prop_name);
|
const Property *prop = object_schema.property_for_name(prop_name);
|
||||||
if (!prop) {
|
if (!prop) {
|
||||||
throw std::runtime_error("Setting invalid property '" + prop_name + "' on object '" + object_schema.name + "'.");
|
throw InvalidPropertyException(object_schema.name, prop_name,
|
||||||
|
"Setting invalid property '" + prop_name + "' on object '" + object_schema.name + "'.");
|
||||||
}
|
}
|
||||||
set_property_value_impl(ctx, *prop, value, try_update);
|
set_property_value_impl(ctx, *prop, value, try_update);
|
||||||
};
|
};
|
||||||
|
@ -117,7 +140,8 @@ namespace realm {
|
||||||
{
|
{
|
||||||
const Property *prop = object_schema.property_for_name(prop_name);
|
const Property *prop = object_schema.property_for_name(prop_name);
|
||||||
if (!prop) {
|
if (!prop) {
|
||||||
throw std::runtime_error("Setting invalid property '" + prop_name + "' on object '" + object_schema.name + "'.");
|
throw InvalidPropertyException(object_schema.name, prop_name,
|
||||||
|
"Getting invalid property '" + prop_name + "' on object '" + object_schema.name + "'.");
|
||||||
}
|
}
|
||||||
return get_property_value_impl<ValueType>(ctx, *prop);
|
return get_property_value_impl<ValueType>(ctx, *prop);
|
||||||
};
|
};
|
||||||
|
@ -128,7 +152,7 @@ namespace realm {
|
||||||
using Accessor = NativeAccessor<ValueType, ContextType>;
|
using Accessor = NativeAccessor<ValueType, ContextType>;
|
||||||
|
|
||||||
if (!m_realm->is_in_transaction()) {
|
if (!m_realm->is_in_transaction()) {
|
||||||
throw std::runtime_error("Can only set property values within a transaction.");
|
throw MutationOutsideTransactionException("Can only set property values within a transaction.");
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t column = property.table_column;
|
size_t column = property.table_column;
|
||||||
|
@ -223,7 +247,7 @@ namespace realm {
|
||||||
using Accessor = NativeAccessor<ValueType, ContextType>;
|
using Accessor = NativeAccessor<ValueType, ContextType>;
|
||||||
|
|
||||||
if (!realm->is_in_transaction()) {
|
if (!realm->is_in_transaction()) {
|
||||||
throw std::runtime_error("Can only create objects within a transaction.");
|
throw MutationOutsideTransactionException("Can only create objects within a transaction.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// get or create our accessor
|
// get or create our accessor
|
||||||
|
@ -244,7 +268,8 @@ namespace realm {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!try_update && row_index != realm::not_found) {
|
if (!try_update && row_index != realm::not_found) {
|
||||||
throw std::runtime_error("Attempting to create an object of type '" + object_schema.name + "' with an exising primary key value.");
|
throw DuplicatePrimaryKeyValueException(object_schema.name, *primary_prop,
|
||||||
|
"Attempting to create an object of type '" + object_schema.name + "' with an exising primary key value.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,7 +292,8 @@ namespace realm {
|
||||||
object.set_property_value_impl(ctx, prop, Accessor::default_value_for_property(ctx, realm.get(), object_schema, prop.name), try_update);
|
object.set_property_value_impl(ctx, prop, Accessor::default_value_for_property(ctx, realm.get(), object_schema, prop.name), try_update);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw std::runtime_error("Missing property value for property " + prop.name);
|
throw MissingPropertyValueException(object_schema.name, prop.name,
|
||||||
|
"Missing property value for property " + prop.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -514,8 +514,12 @@ DuplicatePrimaryKeyValueException::DuplicatePrimaryKeyValueException(std::string
|
||||||
m_object_type(object_type), m_property(property)
|
m_object_type(object_type), m_property(property)
|
||||||
{
|
{
|
||||||
m_what = "Primary key property '" + property.name + "' has duplicate values after migration.";
|
m_what = "Primary key property '" + property.name + "' has duplicate values after migration.";
|
||||||
};
|
}
|
||||||
|
|
||||||
|
DuplicatePrimaryKeyValueException::DuplicatePrimaryKeyValueException(std::string const& object_type, Property const& property, const std::string message) : m_object_type(object_type), m_property(property)
|
||||||
|
{
|
||||||
|
m_what = message;
|
||||||
|
}
|
||||||
|
|
||||||
SchemaValidationException::SchemaValidationException(std::vector<ObjectSchemaValidationException> const& errors) :
|
SchemaValidationException::SchemaValidationException(std::vector<ObjectSchemaValidationException> const& errors) :
|
||||||
m_validation_errors(errors)
|
m_validation_errors(errors)
|
||||||
|
@ -600,3 +604,4 @@ DuplicatePrimaryKeysException::DuplicatePrimaryKeysException(std::string const&
|
||||||
{
|
{
|
||||||
m_what = "Duplicate primary keys for object '" + object_type + "'.";
|
m_what = "Duplicate primary keys for object '" + object_type + "'.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -137,6 +137,8 @@ namespace realm {
|
||||||
class DuplicatePrimaryKeyValueException : public MigrationException {
|
class DuplicatePrimaryKeyValueException : public MigrationException {
|
||||||
public:
|
public:
|
||||||
DuplicatePrimaryKeyValueException(std::string const& object_type, Property const& property);
|
DuplicatePrimaryKeyValueException(std::string const& object_type, Property const& property);
|
||||||
|
DuplicatePrimaryKeyValueException(std::string const& object_type, Property const& property, const std::string message);
|
||||||
|
|
||||||
std::string object_type() const { return m_object_type; }
|
std::string object_type() const { return m_object_type; }
|
||||||
Property const& property() const { return m_property; }
|
Property const& property() const { return m_property; }
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -44,6 +44,8 @@ module.exports = BaseTest.extend({
|
||||||
TestCase.assertEqual(object[prop.name], basicTypesValues[i]);
|
TestCase.assertEqual(object[prop.name], basicTypesValues[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TestCase.assertEqual(object.nonexistent, undefined);
|
||||||
},
|
},
|
||||||
testBasicTypesPropertySetters: function() {
|
testBasicTypesPropertySetters: function() {
|
||||||
var basicTypesValues = [true, 1, 1.1, 1.11, 'string', new Date(1), 'DATA'];
|
var basicTypesValues = [true, 1, 1.1, 1.11, 'string', new Date(1), 'DATA'];
|
||||||
|
|
Loading…
Reference in New Issue