简体   繁体   中英

General error handling in Apache Thrift

TLDR: Is there a better way to notify clients that something unexpected happened on the server without throwing exceptions defined in the IDL.

Just for clarification: I currently use Thrift with C# on the server side (THttpServer, TThreadPooledServer) and a JavaScript AngularJS App on the client (and i have some Tests running the Client foo on C#).

So... I know there is exception handling in Apache Thrift. I can define one in the IDL and tell a service method that there's a possibility of that exception happening. And when that happens the client gets notified that this exception happened and can act accordingly.

But if because of one reason or another the code that gets executed in the handler just goes ahead and dies and throws an exception, the client just gets a "Cannot read, Remote side has closed" error and that's that. I can't really see what happened there and I have to start debugging the server without any clue what to look at. Of course I can log that exception on the server side (which I intend to do) but that can get messy and take a while to look at too.

What i actually want is to let the client at least know stuff happened on the server side and not just have it get a "Yeah. Connection just got closed. No clue why it happened. Happy evening!".

One way to get this would be to make a GeneralExceptions.thrift file and define a general exception in there. Then include this file in every other .thrift file and have every service method expect that exception as one that can happen. And then make huge try catch blocks around my thrift handler methods to catch everything and their mother and wrap it in a neat general thrift exception package and have that go off to the client.

Problem is... having to have those try catch blocks everywhere would be annoying. And having to include one thrift file in all those other files and have every service method declare that it can throw this general exception... well lets just say... it's a ton of work and with people being the way people usually are they could just forget to include the file or not add the exception in those service methods and all the other nice things that tend to happen if you got more then one guy or gal working on any given thing.

So does anyone know another way to notify the client that "stuff" happened on the server without jumping through a ton of hoops?

The server should neither die nor close the connection. I recently fixed exactly that problem for Delphi in Trunk (will be part of 0.9.3). If C# suffers from the same issue, please file a ticket (incl. test case) and/or provide a patch.

What about catching any unexpected exceptions in your server method? That patter is useful with normal COM too, there's not much of a difference:

// this is a service method
void FooBar() {  
  try
  {
    // lets see whether we can divide by zero ...
    var a = 0;
    var b = 1/a;
    Console.Writeln("It works!!");
  }
  catch(e:TException)
  {
    throw; // Thrift exception, don't interfere
  }
  catch(e:Exception)
  {
     throw new TApplicationException( "WTF?");  // or some other exception
  }
}

Problem is... having to have those try catch blocks everywhere would be annoying. And having to include one thrift file in all those other files and have every service method declare that it can throw this general exception... well lets just say... it's a ton of work and with people being the way people usually are they could just forget to include the file or not add the exception in those service methods and all the other nice things that tend to happen if you got more then one guy or gal working on any given thing.

Generate the direct server implementation by some other means and forward the actual work to some other method and/or class:

// this is a service method
MyResult FooBar( MyArg arg1, MyOtherArg arg2) {  
  try
  {
    return pimpl.FooBar(arg1,arg2);  // delegate work via pimpl pattern
  }
  catch(e:TException)
  {
    throw; // Thrift exception, don't interfere
  }
  catch(e:Exception)
  {
     throw new TApplicationException( "WTF?");  // or some other exception
  }
}

This is very straightforward and can be easily automated.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM