Various Thrift fixes, including Application Exception support in Ruby, better errror messages across languages, etc.
Reviewed By: thrift
git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@665058 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/php/src/transport/TPhpStream.php b/lib/php/src/transport/TPhpStream.php
index 8a4fb0a..03837a8 100644
--- a/lib/php/src/transport/TPhpStream.php
+++ b/lib/php/src/transport/TPhpStream.php
@@ -40,13 +40,13 @@
if ($this->read_) {
$this->inStream_ = @fopen('php://input', 'r');
if (!is_resource($this->inStream_)) {
- throw new Exception('TPhpStream: Could not open php://input');
+ throw new TException('TPhpStream: Could not open php://input');
}
}
if ($this->write_) {
$this->outStream_ = @fopen('php://output', 'w');
if (!is_resource($this->outStream_)) {
- throw new Exception('TPhpStream: Could not open php://output');
+ throw new TException('TPhpStream: Could not open php://output');
}
}
}
@@ -71,7 +71,7 @@
public function read($len) {
$data = @fread($this->inStream_, $len);
if (!$data) {
- throw new Exception('TPhpStream: Could not read '.$len.' bytes');
+ throw new TException('TPhpStream: Could not read '.$len.' bytes');
}
return $data;
}
@@ -80,7 +80,7 @@
while (strlen($buf) > 0) {
$got = @fwrite($this->outStream_, $buf);
if ($got === 0 || $got === FALSE) {
- throw new Exception('TPhpStream: Could not write '.strlen($buf).' bytes');
+ throw new TException('TPhpStream: Could not write '.strlen($buf).' bytes');
}
$buf = substr($buf, $got);
}
diff --git a/lib/php/src/transport/TSocket.php b/lib/php/src/transport/TSocket.php
index 1600b6f..cce3a44 100644
--- a/lib/php/src/transport/TSocket.php
+++ b/lib/php/src/transport/TSocket.php
@@ -160,7 +160,7 @@
if ($this->debug_) {
call_user_func($this->debugHandler_, $error);
}
- throw new Exception($error);
+ throw new TException($error);
}
stream_set_timeout($this->handle_, 0, $this->sendTimeout_*1000);
@@ -197,17 +197,17 @@
if ($buf === FALSE || $buf === '') {
$md = stream_get_meta_data($this->handle_);
if ($md['timed_out']) {
- throw new Exception('TSocket: timed out reading '.$len.' bytes from '.
- $this->host_.':'.$this->port_);
+ throw new TException('TSocket: timed out reading '.$len.' bytes from '.
+ $this->host_.':'.$this->port_);
} else {
- throw new Exception('TSocket: Could not read '.$len.' bytes from '.
- $this->host_.':'.$this->port_);
+ throw new TException('TSocket: Could not read '.$len.' bytes from '.
+ $this->host_.':'.$this->port_);
}
} else if (($sz = strlen($buf)) < $len) {
$md = stream_get_meta_data($this->handle_);
if ($md['timed_out']) {
- throw new Exception('TSocket: timed out reading '.$len.' bytes from '.
- $this->host_.':'.$this->port_);
+ throw new TException('TSocket: timed out reading '.$len.' bytes from '.
+ $this->host_.':'.$this->port_);
} else {
$pre .= $buf;
$len -= $sz;
@@ -233,11 +233,11 @@
if ($data === FALSE || $data === '') {
$md = stream_get_meta_data($this->handle_);
if ($md['timed_out']) {
- throw new Exception('TSocket: timed out reading '.$len.' bytes from '.
- $this->host_.':'.$this->port_);
+ throw new TException('TSocket: timed out reading '.$len.' bytes from '.
+ $this->host_.':'.$this->port_);
} else {
- throw new Exception('TSocket: Could not read '.$len.' bytes from '.
- $this->host_.':'.$this->port_);
+ throw new TException('TSocket: Could not read '.$len.' bytes from '.
+ $this->host_.':'.$this->port_);
}
}
return $data;
@@ -258,11 +258,11 @@
if ($got === 0 || $got === FALSE) {
$md = stream_get_meta_data($this->handle_);
if ($md['timed_out']) {
- throw new Exception('TSocket: timed out writing '.$len.' bytes from '.
- $this->host_.':'.$this->port_);
+ throw new TException('TSocket: timed out writing '.$len.' bytes from '.
+ $this->host_.':'.$this->port_);
} else {
- throw new Exception('TSocket: Could not write '.strlen($buf).' bytes '.
- $this->host_.':'.$this->port_);
+ throw new TException('TSocket: Could not write '.strlen($buf).' bytes '.
+ $this->host_.':'.$this->port_);
}
}
$buf = substr($buf, $got);
@@ -275,8 +275,8 @@
public function flush() {
$ret = fflush($this->handle_);
if ($ret === FALSE) {
- throw new Exception('TSocket: Could not flush: '.
- $this->host_.':'.$this->port_);
+ throw new TException('TSocket: Could not flush: '.
+ $this->host_.':'.$this->port_);
}
}
}
diff --git a/lib/php/src/transport/TSocketPool.php b/lib/php/src/transport/TSocketPool.php
index 9e5ebcd..b3efb2d 100644
--- a/lib/php/src/transport/TSocketPool.php
+++ b/lib/php/src/transport/TSocketPool.php
@@ -221,7 +221,7 @@
// Successful connection, return now
return;
- } catch (Exception $x) {
+ } catch (TException $tx) {
// Connection failed
}
}
@@ -268,7 +268,7 @@
if ($this->debug_) {
call_user_func($this->debugHandler_, $error);
}
- throw new Exception($error);
+ throw new TException($error);
}
}
diff --git a/lib/py/src/Thrift.py b/lib/py/src/Thrift.py
index a1ec6cc..aeca9b9 100644
--- a/lib/py/src/Thrift.py
+++ b/lib/py/src/Thrift.py
@@ -43,6 +43,7 @@
def __init__(self, message=None):
Exception.__init__(self, message)
+ self.message = message
class TApplicationException(TException):
diff --git a/lib/py/src/transport/TSocket.py b/lib/py/src/transport/TSocket.py
index 1f9c480..280d6aa 100644
--- a/lib/py/src/transport/TSocket.py
+++ b/lib/py/src/transport/TSocket.py
@@ -13,7 +13,6 @@
"""Socket implementation of TTransport base."""
-
def __init__(self, host='localhost', port=9090):
self.host = host
self.port = port
@@ -34,7 +33,7 @@
self.handle = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.handle.connect((self.host, self.port))
except socket.error, e:
- raise TTransportException(TTransportException.NOT_OPEN)
+ raise TTransportException(TTransportException.NOT_OPEN, 'Could not connect to %s:%d' % (self.host, self.port))
def close(self):
if self.handle != None:
diff --git a/lib/py/src/transport/TTransport.py b/lib/py/src/transport/TTransport.py
index b655b32..305c10b 100644
--- a/lib/py/src/transport/TTransport.py
+++ b/lib/py/src/transport/TTransport.py
@@ -14,11 +14,11 @@
"""Custom Transport Exception class"""
- UNKNOWN = 0,
- NOT_OPEN = 1,
- ALREADY_OPEN = 2,
- TIMED_OUT = 3,
- END_OF_FILE = 4,
+ UNKNOWN = 0
+ NOT_OPEN = 1
+ ALREADY_OPEN = 2
+ TIMED_OUT = 3
+ END_OF_FILE = 4
def __init__(self, type=UNKNOWN, message=None):
TException.__init__(self, message)
diff --git a/lib/rb/lib/thrift/protocol/tprotocol.rb b/lib/rb/lib/thrift/protocol/tprotocol.rb
index 4376024..3c13b4b 100644
--- a/lib/rb/lib/thrift/protocol/tprotocol.rb
+++ b/lib/rb/lib/thrift/protocol/tprotocol.rb
@@ -8,26 +8,8 @@
#
# Author: Mark Slee <mcslee@facebook.com>
#
-class TType
- STOP = 0
- VOID = 1
- BOOL = 2
- BYTE = 3
- DOUBLE = 4
- I16 = 6
- I32 = 8
- I64 = 10
- STRING = 11
- STRUCT = 12
- MAP = 13
- SET = 14
- LIST = 15
-end
-class TMessageType
- CALL = 1
- REPLY = 2
-end
+require 'thrift/thrift'
class TProtocol
diff --git a/lib/rb/lib/thrift/thrift.rb b/lib/rb/lib/thrift/thrift.rb
index 16c7174..2b9ebbb 100644
--- a/lib/rb/lib/thrift/thrift.rb
+++ b/lib/rb/lib/thrift/thrift.rb
@@ -8,6 +8,99 @@
#
# Author: Mark Slee <mcslee@facebook.com>
#
+
+class TType
+ STOP = 0
+ VOID = 1
+ BOOL = 2
+ BYTE = 3
+ DOUBLE = 4
+ I16 = 6
+ I32 = 8
+ I64 = 10
+ STRING = 11
+ STRUCT = 12
+ MAP = 13
+ SET = 14
+ LIST = 15
+end
+
+class TMessageType
+ CALL = 1
+ REPLY = 2
+ EXCEPTION = 3
+end
+
module TProcessor
def process(iprot, oprot); nil; end
end
+
+class TException < StandardError
+ def initialize(message)
+ super(message)
+ @message = message
+ end
+
+ attr_reader :message
+end
+
+class TApplicationException < TException
+
+ UNKNOWN = 0
+ UNKNOWN_METHOD = 1
+ INVALID_MESSAGE_TYPE = 2
+ WRONG_METHOD_NAME = 3
+ BAD_SEQUENCE_ID = 4
+ MISSING_RESULT = 5
+
+ attr_reader :type
+
+ def initialize(type=UNKNOWN, message=nil)
+ super(message)
+ @type = type
+ end
+
+ def read(iprot)
+ iprot.readStructBegin()
+ while true
+ fname, ftype, fid = iprot.readFieldBegin()
+ if (ftype === TType::STOP)
+ break
+ end
+ if (fid == 1)
+ if (ftype === TType::STRING)
+ @message = iprot.readString();
+ else
+ iprot.skip(ftype)
+ end
+ elsif (fid == 2)
+ if (ftype === TType::I32)
+ @type = iprot.readI32();
+ else
+ iprot.skip(ftype)
+ end
+ else
+ iprot.skip(ftype)
+ end
+ iprot.readFieldEnd()
+ end
+ iprot.readStructEnd()
+ end
+
+ def write(oprot)
+ oprot.writeStructBegin('TApplicationException')
+ if (@message != nil)
+ oprot.writeFieldBegin('message', TType::STRING, 1)
+ oprot.writeString(@message)
+ oprot.writeFieldEnd()
+ end
+ if (@type != nil)
+ oprot.writeFieldBegin('type', TType::I32, 2)
+ oprot.writeI32(@type)
+ oprot.writeFieldEnd()
+ end
+ oprot.writeFieldStop()
+ oprot.writeStructEnd()
+ end
+
+end
diff --git a/lib/rb/lib/thrift/transport/tsocket.rb b/lib/rb/lib/thrift/transport/tsocket.rb
index d2e197f..9de2b8e 100644
--- a/lib/rb/lib/thrift/transport/tsocket.rb
+++ b/lib/rb/lib/thrift/transport/tsocket.rb
@@ -23,7 +23,11 @@
end
def open()
- @handle = TCPSocket.new(@host, @port)
+ begin
+ @handle = TCPSocket.new(@host, @port)
+ rescue StandardError
+ raise TTransportException.new(TTransportException::NOT_OPEN, "Could not connect to #{@host}:#{@port}")
+ end
end
def isOpen()
@@ -31,15 +35,23 @@
end
def write(str)
- @handle.write(str)
+ begin
+ @handle.write(str)
+ rescue StandardError
+ raise TTransportException.new(TTransportException::NOT_OPEN)
+ end
end
def read(sz)
- data = @handle.recv(sz)
- if (data.length == 0)
- raise TTransportException.new("TSocket: Could not read #{sz} bytes from #{@host}:#{@port}")
+ begin
+ data = @handle.recv(sz)
+ if (data.length == 0)
+ raise TTransportException.new("TSocket: Could not read #{sz} bytes from #{@host}:#{@port}")
+ end
+ return data
+ rescue StandardError
+ raise TTransportException.new(TTransportException::NOT_OPEN)
end
- return data
end
def close()
diff --git a/lib/rb/lib/thrift/transport/ttransport.rb b/lib/rb/lib/thrift/transport/ttransport.rb
index 92c606a..5b9b8b1 100644
--- a/lib/rb/lib/thrift/transport/ttransport.rb
+++ b/lib/rb/lib/thrift/transport/ttransport.rb
@@ -8,10 +8,24 @@
#
# Author: Mark Slee <mcslee@facebook.com>
#
-class TTransportException < StandardError
- def initialize(message)
+
+require 'thrift/thrift'
+
+class TTransportException < TException
+
+ UNKNOWN = 0
+ NOT_OPEN = 1
+ ALREADY_OPEN = 2
+ TIMED_OUT = 3
+ END_OF_FILE = 4
+
+ attr_reader :type
+
+ def initialize(type=UNKNOWN, message=nil)
super(message)
- end
+ @type = type
+ end
+
end
class TTransport
@@ -54,5 +68,42 @@
return trans
end
end
+
+class TBufferedTransport < TTransport
+ def initialize(transport)
+ @transport = transport
+ @wbuf = ''
+ end
+
+ def isOpen()
+ return @transport.isOpen()
+ end
-
+ def open()
+ @transport.open()
+ end
+
+ def close()
+ @transport.close()
+ end
+
+ def read(sz)
+ return @transport.read(sz)
+ end
+
+ def write(buf)
+ @wbuf += buf
+ end
+
+ def flush()
+ @transport.write(@wbuf)
+ @transport.flush()
+ @wbuf = ''
+ end
+end
+
+class TBufferedTransportFactory < TTransportFactory
+ def getTransport(transport)
+ return TBufferedTransport.new(transport)
+ end
+end