[omniORB] Propogating Exceptions

Greg Jones Greg_Jones@mail.crc.com
Thu, 24 Sep 1998 12:47:25 -0400


In response to a users request, the following is my IDL and C++ source
code that I am using. I am trying to raise an exception in the server
(code titled Printers_i.cc) and have that exception propogate back to
the client (code titled Printers_client.cc). Any help is appreciated.
The lines where I intend on throwing the exception are blocked off by
"*******" in the Printers_i.cc code and I intend on catching the
exception in the client code where I blocked the code with "********". 

//Printers IDL

module Print_Function
{
	interface Printers
	{
		exception Printer_Not_Found {};
		exception Printing_Failed {};

		void print_message
		(
			in string in_request,
			out string out_printing  
		)
		raises(Printer_Not_Found, Printing_Failed);
       		
	};

};


// Printers_i.cc (server code)
//
#include <stdlib.h>
#include <tcl.h>
#include <string.h>
#include "Printers.hh"

//                                   

;
//                                    

class Printers_i : public virtual Print_Function::_sk_Printers {
public:
Printers_i() {}
virtual ~Printers_i() {}
//                                      

//                                     
virtual void print_message(const char *in_request, char *
&out_printing);
};
//                                     

//                                     

void  
Printers_i::print_message(const char *in_request, char * &out_printing)
{
static int row=0;

char *s1 = "print file 11";


//*****************************************************************
//*****************************************************************

//AS A TEST CASE, I WANT TO THROW BACK THE "Printer_Not_Found" EXCEPTION
IF
//IF THE CLIENT TRIES SENDS THE SERVER THE "print file 11" REQUEST.


if(strcmp(in_request,s1)==0){
  throw Printer_Function::Printers::Printer_Not_Found();
};

//*****************************************************************
//*****************************************************************


static char * _Dout_printing[3]; 
   _Dout_printing[0] = 
 (char *) "file 00 is printing";
    _Dout_printing[1] = 
 (char *) "file 11 is printing";
    _Dout_printing[2] = 
 (char *) "file 22 is printing";


//                                   
/* BEHAVIORAL DATA STARTS HERE... */
char *  p0;
p0 = CORBA::string_dup(_Dout_printing[row % 3]);
Tcl_Sleep(3000);
++row; 

out_printing = p0;

/* BEHAVIORAL DATA ENDS HERE... */
}
//END OF THE GENERATED SERVER CODE (Printers_i.cc)



//BEGINNING OF THE CLIENT CODE (Printers_client.cc)

//Printers_client.cc (client code)
#include <iostream.h>
#include <stdlib.h>
#include "Printers.hh"
#include "Printers_iterators.cc"

 void print_time();
//                                       $RISE - End gen_clnt_preamble()

static 
CORBA::Object_ptr
getObjectReference(CORBA::ORB_ptr orb, const char *ifname)
{
  CosNaming::NamingContext_var rootContext;
  
  try {
    // Obtain a ref to the root context of the Name service:
    CORBA::Object_var initServ;
    initServ = orb->resolve_initial_references("NameService");

    // Narrow the object returned by resolve_initial_references()
    // to a CosNaming::NamingContext object:
    rootContext = CosNaming::NamingContext::_narrow(initServ);
    if (CORBA::is_nil(rootContext)) 
      {
        cerr << "Failed to narrow naming context." << endl;
        return CORBA::Object::_nil();
      }
  }
  catch(CORBA::ORB::InvalidName& ex) {
    cerr << "Service required is invalid [does not exist]." << endl;
    return CORBA::Object::_nil();
  }


  // Create a name object, containing the name test/context:
  CosNaming::Name name;
  name.length(2);

  name[0].id   = (const char*) "test";       // string copied
  name[0].kind = (const char*) "my_context"; // string copied
  name[1].id   = (const char*) ifname; 
  name[1].kind = (const char*) "Object";
  // Note on kind: The kind field is used to indicate the type
  // of the object. This is to avoid conventions such as that used
  // by files (name.type -- e.g. test.ps = postscript etc.)

  
  CORBA::Object_ptr obj;
  try {
    // Resolve the name to an object reference, and assign the reference 
    // returned to a CORBA::Object:
    obj = rootContext->resolve(name);
  }
  catch(CosNaming::NamingContext::NotFound& ex)
    {
      // This exception is thrown if any of the components of the
      // path [contexts or the object] aren't found:
      cerr << "Context not found for " << ifname << endl;
      return CORBA::Object::_nil();
    }
  catch (CORBA::COMM_FAILURE& ex) {
    cerr << "Caught system exception COMM_FAILURE, unable to contact the
"
         << "naming service." << endl;
    return CORBA::Object::_nil();
  }
  catch(omniORB::fatalException& ex) {
    throw;
  }
  catch (...) {
    cerr << "Caught a system exception while using the naming
service."<< endl;
    return CORBA::Object::_nil();
  }
  return obj;
}
//                                       $RISE - Begin
gen_clnt_doit_method()

void
do_Print_FunctionPrinters(CORBA::Object_ptr obj)
{
  Print_Function::Printers_var e =
Print_Function::Printers::_narrow(obj);

  if (CORBA::is_nil(e)) {
    cerr << "do_PrintersPrint_Function: cannot invoke on a nil obj
reference.\n" << endl;
    return;
  }

 register int i; // index for each record. 
//                                       $RISE - End
gen_clnt_doit_method()

//                                       $RISE - Begin
gen_clnt_decl_for_ins()
CORBA::String_var in_request_print_message[3]={ 
(const char*) "print file 00",
(const char*) "print file 11",
(const char*) "print file 22"
};
//                                       $RISE - End
gen_clnt_decl_for_ins()

//                                       $RISE - Begin
gen_clnt_decl_for_outs()
  CORBA::String_var out_printing_print_message_out;

//                                       $RISE - End
gen_clnt_decl_for_outs()

//                                       $RISE - Begin
clnt_build_parmlist()
//                                       $RISE - End
clnt_build_parmlist()
//                                       $RISE - Begin
gen_clnt_behavior()
 for (i=0; i<3 ; ++i) {
  print_time();
  cout <<"Calling print_message()" << endl;
  cout <<"    Inputs: "<<endl<< "            "<<
in_request_print_message[i] << endl;
  e->print_message(in_request_print_message[i],
out_printing_print_message_out);
  cout << endl ; 
  cout <<"    Outputs: "<<endl<< "             "<<
out_printing_print_message_out << endl;

  cout << endl;
  print_time();
  cout <<"---------------------------------------- "  << endl;
 }
//                                       $RISE - End gen_clnt_behavior()

}
//                                       $RISE - Begin gen_clnt_body()

extern void do_Print_FunctionPrinters(CORBA::Object_ptr obj);

static CORBA::Object_ptr getObjectReference(CORBA::ORB_ptr orb, const
char *ifname);

int
main0 (int argc, char **argv) 
{
  CORBA::ORB_ptr orb = CORBA::ORB_init(argc,argv,"omniORB2");
  CORBA::BOA_ptr boa = orb->BOA_init(argc,argv,"omniORB2_BOA");

  try {
    CORBA::Object_var obj = getObjectReference(orb, "Printers");
    do_Print_FunctionPrinters(obj);
  }
  catch(CORBA::COMM_FAILURE& ex) {
    cerr << "Caught system exception COMM_FAILURE, unable to contact the
"
         << "object." << endl;
  }
  catch(omniORB::fatalException& ex) {
    cerr << "Caught omniORB2 fatalException. This indicates a bug is
caught "
         << "within omniORB2.\nPlease send a bug report.\n"
         << "The exception was thrown in file: " << ex.file() << "\n"
         << "                            line: " << ex.line() << "\n"
         << "The error message is: " << ex.errmsg() << endl;
  }
//****************************************************************************
//****************************************************************************

//THIS IS WHERE I WANT TO CATCH MY USER DEFINED EXCEPTION THROWN BY THE
SERVER
  catch(const UserException) {
    cerr << "Printer_Not_Found EXCEPTION THROWN IN CLIENT CODE" << endl;
  }

//*****************************************************************************
//*****************************************************************************

  catch(...) {
    cerr << "THIS IS A GENERAL EXCEPTION THROWN IN CLIENT CODE" << endl;
  }

  return 0;
}

// 

int main (int argc, char **argv) 
{
main0(argc, argv);
  return(0); 
}


//END OF THE CLIENT CODE (Printers_client.cc)