THRIFT-4562 Calling wrong exception CTOR leads to "call failed: unknown result" instead of the real exception being thrown
Client: Delphi
Patch: Jens Geyer
This closes #1551
diff --git a/compiler/cpp/src/thrift/generate/t_delphi_generator.cc b/compiler/cpp/src/thrift/generate/t_delphi_generator.cc
index db06827..8bd77e8 100644
--- a/compiler/cpp/src/thrift/generate/t_delphi_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_delphi_generator.cc
@@ -131,7 +131,7 @@
bool is_xception_class,
bool is_union,
bool is_xception_factory,
- std::string xception_factroy_name);
+ std::string xception_factory_name);
void generate_delphi_clear_union_value(ostream& out,
std::string cls_prefix,
std::string name,
@@ -141,7 +141,7 @@
bool is_xception_class,
bool is_union,
bool is_xception_factory,
- std::string xception_factroy_name);
+ std::string xception_factory_name);
void generate_delphi_isset_reader_impl(ostream& out,
std::string cls_prefix,
std::string name,
@@ -1483,8 +1483,6 @@
indent_up_impl();
if (is_exception && (!is_x_factory)) {
indent_impl(out) << "inherited Create('');" << endl;
- indent_impl(out) << "F" << exception_factory_name << " := T" << exception_factory_name
- << "Impl.Create;" << endl;
} else {
indent_impl(out) << "inherited;" << endl;
}
@@ -1530,6 +1528,19 @@
indent_down_impl();
indent_impl(out) << "end;" << endl << endl;
+ if (is_exception && (!is_x_factory)) {
+ indent_impl(out) << "function " << cls_prefix << cls_nm << "." << exception_factory_name
+ << ": I" << exception_factory_name << ";" << endl;
+ indent_impl(out) << "begin" << endl;
+ indent_up_impl();
+ indent_impl(out) << "if F" << exception_factory_name << " = nil" << endl;
+ indent_impl(out) << "then F" << exception_factory_name << " := T" << exception_factory_name << "Impl.Create;" << endl;
+ indent_impl(out) << endl;
+ indent_impl(out) << "result := F" << exception_factory_name << ";" << endl;
+ indent_down_impl();
+ indent_impl(out) << "end;" << endl << endl;
+ }
+
if (tstruct->is_union()) {
indent_impl(out) << "procedure " << cls_prefix << cls_nm << "."
<< "ClearUnionValues;" << endl;
@@ -1813,8 +1824,7 @@
if (is_exception && (!is_x_factory)) {
out << endl;
indent(out) << "// Exception Factory" << endl;
- indent(out) << "property " << exception_factory_name << ": " << struct_intf_name << " read F"
- << exception_factory_name << " write F" << exception_factory_name << ";" << endl;
+ indent(out) << "function " << exception_factory_name << ": " << struct_intf_name << ";" << endl;
}
if ((!is_exception) || is_x_factory) {
@@ -3450,7 +3460,7 @@
bool is_xception_class,
bool is_union,
bool is_xception_factory,
- std::string xception_factroy_name) {
+ std::string xception_factory_name) {
(void)type;
t_type* ftype = tfield->get_type();
@@ -3471,7 +3481,7 @@
indent_impl(out) << fieldPrefix << prop_name(tfield, is_xception_class) << " := Value;" << endl;
if (is_xception_class && (!is_xception_factory)) {
- indent_impl(out) << "F" << xception_factroy_name << "." << prop_name(tfield, is_xception_class)
+ indent_impl(out) << xception_factory_name << "." << prop_name(tfield, is_xception_class)
<< " := Value;" << endl;
}
@@ -3538,7 +3548,7 @@
indent_impl(out) << "Result := " << exception_cls_nm << ".Create;" << endl;
string factory_name = normalize_clsnm(tstruct->get_name(), "", true) + "Factory";
- indent_impl(out) << "Result." << factory_name << " := Self;" << endl;
+ indent_impl(out) << "Result.F" << factory_name << " := Self;" << endl;
const vector<t_field*>& fields = tstruct->get_members();
vector<t_field*>::const_iterator f_iter;
@@ -3548,8 +3558,7 @@
for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
propname = prop_name(*f_iter, is_exception);
if ((*f_iter)->get_req() != t_field::T_REQUIRED) {
- indent_impl(out) << "if __isset_" << propname << " then" << endl;
- indent_impl(out) << "begin" << endl;
+ indent_impl(out) << "if __isset_" << propname << " then begin" << endl;
indent_up_impl();
}
indent_impl(out) << "Result." << propname << " := " << propname << ";" << endl;
diff --git a/lib/delphi/test/TestServer.pas b/lib/delphi/test/TestServer.pas
index 4400c34..69cb175 100644
--- a/lib/delphi/test/TestServer.pas
+++ b/lib/delphi/test/TestServer.pas
@@ -164,7 +164,7 @@
if (arg = 'TException') then
begin
- raise TException.Create('');
+ raise TException.Create('TException');
end;
// else do not throw anything
diff --git a/lib/delphi/test/serializer/TestSerializer.dpr b/lib/delphi/test/serializer/TestSerializer.dpr
index 4360a73..51e22a4 100644
--- a/lib/delphi/test/serializer/TestSerializer.dpr
+++ b/lib/delphi/test/serializer/TestSerializer.dpr
@@ -35,7 +35,7 @@
Thrift.Serializer in '..\..\src\Thrift.Serializer.pas',
Thrift.Stream in '..\..\src\Thrift.Stream.pas',
Thrift.TypeRegistry in '..\..\src\Thrift.TypeRegistry.pas',
- ReservedKeywords,
+ System_,
DebugProtoTest,
TestSerializer.Data;