THRIFT-809 Javascript client: Please make required fields actually required.

Patch: noazark

Github Pull Request: This closes #232
diff --git a/compiler/cpp/src/generate/t_js_generator.cc b/compiler/cpp/src/generate/t_js_generator.cc
index 74ec15a..12b7daa 100644
--- a/compiler/cpp/src/generate/t_js_generator.cc
+++ b/compiler/cpp/src/generate/t_js_generator.cc
@@ -708,8 +708,12 @@
 
     for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
         out << indent() << indent() << "if (args." << (*m_iter)->get_name() << " !== undefined) {" << endl
-            << indent() << indent() << indent() << "this." << (*m_iter)->get_name() << " = args." << (*m_iter)->get_name()  << ";" << endl
-            << indent() << indent() << "}" << endl;
+            << indent() << indent() << indent() << "this." << (*m_iter)->get_name() << " = args." << (*m_iter)->get_name()  << ";" << endl;
+        if (!(*m_iter)->get_req()) {
+          out << indent() << indent() << "} else {" << endl
+              << indent() << indent() << indent() << "throw new Thrift.TProtocolException(Thrift.TProtocolExceptionType.UNKNOWN, 'Required field " << (*m_iter)->get_name() << " is unset!');" << endl;
+        }
+        out << indent() << indent() << "}" << endl;
         if (gen_ts_) {
           f_types_ts_ << (*m_iter)->get_name() << ts_get_req(*m_iter) << ": " << ts_get_type((*m_iter)->get_type()) << "; ";
         }
diff --git a/lib/nodejs/lib/thrift/protocol.js b/lib/nodejs/lib/thrift/protocol.js
index 6c4d9e6..c8e8a4e 100644
--- a/lib/nodejs/lib/thrift/protocol.js
+++ b/lib/nodejs/lib/thrift/protocol.js
@@ -25,22 +25,6 @@
 
 var InputBufferUnderrunError = require('./transport').InputBufferUnderrunError;
 
-var UNKNOWN = 0,
-    INVALID_DATA = 1,
-    NEGATIVE_SIZE = 2,
-    SIZE_LIMIT = 3,
-    BAD_VERSION = 4,
-    NOT_IMPLEMENTED = 5,
-    DEPTH_LIMIT = 6;
-
-var TProtocolException = function(type, message) {
-  Error.call(this, message);
-  this.name = 'TProtocolException';
-  this.type = type;
-};
-util.inherits(TProtocolException, Error);
-
-
 //
 // BINARY PROTOCOL
 //
@@ -186,14 +170,14 @@
     var version = sz & VERSION_MASK;
     if (version != VERSION_1) {
       console.log("BAD: " + version);
-      throw new TProtocolException(BAD_VERSION, "Bad version in readMessageBegin: " + sz);
+      throw new Thrift.TProtocolException(Thrift.TProtocolExceptionType.BAD_VERSION, "Bad version in readMessageBegin: " + sz);
     }
     type = sz & TYPE_MASK;
     name = this.readString();
     seqid = this.readI32();
   } else {
     if (this.strictRead) {
-      throw new TProtocolException(BAD_VERSION, "No protocol version header");
+      throw new Thrift.TProtocolException(Thrift.TProtocolExceptionType.BAD_VERSION, "No protocol version header");
     }
     name = this.trans.read(sz);
     type = this.readByte();
@@ -550,7 +534,7 @@
     case TCompactProtocol.Types.CT_STRUCT:
       return Type.STRUCT;
     default:
-      throw new TProtocolException(INVALID_DATA, "Unknown type: " + type);
+      throw new Thrift.TProtocolException(Thift.TProtocolExceptionType.INVALID_DATA, "Unknown type: " + type);
   }
   return Type.STOP;
 };
@@ -808,7 +792,7 @@
     l = new Int64(l);
   }
   if (! (l instanceof Int64)) {
-    throw new TProtocolException(INVALID_DATA, "Expected Int64 or Number, found: " + l);
+    throw new Thrift.TProtocolException(Thrift.TProtocolExceptionType.INVALID_DATA, "Expected Int64 or Number, found: " + l);
   }
   var hi = l.buffer.readUInt32BE(0, true);
   var lo = l.buffer.readUInt32BE(4, true);
@@ -907,8 +891,8 @@
 TCompactProtocol.prototype.readMapBegin = function() {
   var msize = this.readVarint32();
   if (msize < 0) {
-    throw new TProtocolException(NEGATIVE_SIZE, "Negative map size");
-  } 
+    throw new Thrift.TProtocolException(Thrift.TProtocolExceptionType.NEGATIVE_SIZE, "Negative map size");
+  }
 
   var kvType = 0;
   if (msize !== 0) {
@@ -932,8 +916,8 @@
   }
 
   if (lsize < 0) {
-    throw TProtocolException(NEGATIVE_SIZE, "Negative list size");
-  } 
+    throw new Thrift.TProtocolException(Thrift.TProtocolExceptionType.NEGATIVE_SIZE, "Negative list size");
+  }
 
   var elemType = this.getTType(size_and_type & 0x0000000f);
 
@@ -993,7 +977,7 @@
 
   // Catch error cases
   if (size < 0) {
-    throw new TProtocolException(NEGATIVE_SIZE, "Negative binary/string size");
+    throw new Thrift.TProtocolException(Thrift.TProtocolExceptionType.NEGATIVE_SIZE, "Negative binary/string size");
   }
   var value = this.trans.readString(size);
 
@@ -1042,7 +1026,7 @@
       break;
     }
     if (rsize >= 10) {
-      throw new TProtocolException(INVALID_DATA, "Variable-length int over 10 bytes.");
+      throw new Thrift.TProtocolException(Thrift.TProtocolExceptionType.INVALID_DATA, "Variable-length int over 10 bytes.");
     }
   }
   var i64 = new Int64(hi, lo);
diff --git a/lib/nodejs/lib/thrift/thrift.js b/lib/nodejs/lib/thrift/thrift.js
index aabe11f..e02bb7d 100644
--- a/lib/nodejs/lib/thrift/thrift.js
+++ b/lib/nodejs/lib/thrift/thrift.js
@@ -126,6 +126,24 @@
   output.writeStructEnd();
 };
 
+var TProtocolExceptionType = exports.TProtocolExceptionType = {
+  UNKNOWN: 0,
+  INVALID_DATA: 1,
+  NEGATIVE_SIZE: 2,
+  SIZE_LIMIT: 3,
+  BAD_VERSION: 4,
+  NOT_IMPLEMENTED: 5,
+  DEPTH_LIMIT: 6
+}
+
+
+var TProtocolException = exports.TProtocolException = function(type, message) {
+  Error.call(this, message);
+  this.name = 'TProtocolException';
+  this.type = type;
+};
+util.inherits(TProtocolException, Error);
+
 exports.objectLength = function(obj) {
   return Object.keys(obj).length;
 };