Skip to content

Commit 59cd72c

Browse files
committed
Merge pull request #114 from Sage/dont-throw
Dont throw
2 parents 0997a32 + 51bc4a9 commit 59cd72c

File tree

5 files changed

+63
-67
lines changed

5 files changed

+63
-67
lines changed

src/connection.cpp

Lines changed: 53 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,11 @@ Handle<Value> Connection::Execute(const Arguments& args) {
5757

5858
String::Utf8Value sqlVal(sql);
5959

60-
ExecuteBaton* baton;
61-
try {
62-
baton = new ExecuteBaton(connection, *sqlVal, &values, &callback);
63-
} catch(NodeOracleException &ex) {
64-
return scope.Close(ThrowException(Exception::Error(String::New(ex.getMessage().c_str()))));
60+
ExecuteBaton* baton = new ExecuteBaton(connection, *sqlVal, &values, &callback);
61+
if (baton->error) {
62+
Local<String> message = String::New(baton->error->c_str());
63+
delete baton;
64+
return scope.Close(ThrowException(Exception::Error(message)));
6565
}
6666

6767
uv_work_t* req = new uv_work_t();
@@ -102,12 +102,7 @@ Handle<Value> Connection::Commit(const Arguments& args) {
102102

103103
REQ_FUN_ARG(0, callback);
104104

105-
CommitBaton* baton;
106-
try {
107-
baton = new CommitBaton(connection, &callback);
108-
} catch(NodeOracleException &ex) {
109-
return scope.Close(ThrowException(Exception::Error(String::New(ex.getMessage().c_str()))));
110-
}
105+
CommitBaton* baton = new CommitBaton(connection, &callback);
111106

112107
uv_work_t* req = new uv_work_t();
113108
req->data = baton;
@@ -124,12 +119,7 @@ Handle<Value> Connection::Rollback(const Arguments& args) {
124119

125120
REQ_FUN_ARG(0, callback);
126121

127-
RollbackBaton* baton;
128-
try {
129-
baton = new RollbackBaton(connection, &callback);
130-
} catch(NodeOracleException &ex) {
131-
return scope.Close(ThrowException(Exception::Error(String::New(ex.getMessage().c_str()))));
132-
}
122+
RollbackBaton* baton = new RollbackBaton(connection, &callback);
133123

134124
uv_work_t* req = new uv_work_t();
135125
req->data = baton;
@@ -172,7 +162,8 @@ void RandomBytesFree(char* data, void* hint) {
172162
delete[] data;
173163
}
174164

175-
int Connection::SetValuesOnStatement(oracle::occi::Statement* stmt, vector<value_t*> &values) {
165+
int Connection::SetValuesOnStatement(oracle::occi::Statement* stmt, ExecuteBaton* baton) {
166+
std::vector<value_t*> &values = baton->values;
176167
uint32_t index = 1;
177168
int outputParam = -1;
178169
OutParam * outParam = NULL;
@@ -254,19 +245,21 @@ int Connection::SetValuesOnStatement(oracle::occi::Statement* stmt, vector<value
254245
{
255246
ostringstream oss;
256247
oss << "SetValuesOnStatement: Unknown OutParam type: " << outParamType;
257-
throw NodeOracleException(oss.str());
248+
baton->error = new std::string(oss.str());
249+
return -2;
258250
}
259251
}
260252
outputParam = index;
261253
break;
262254
default:
263-
throw NodeOracleException("SetValuesOnStatement: Unhandled value type");
255+
baton->error = new std::string("SetValuesOnStatement: Unhandled value type");
256+
return -2;
264257
}
265258
}
266259
return outputParam;
267260
}
268261

269-
void Connection::CreateColumnsFromResultSet(oracle::occi::ResultSet* rs, vector<column_t*> &columns) {
262+
void Connection::CreateColumnsFromResultSet(oracle::occi::ResultSet* rs, ExecuteBaton* baton, vector<column_t*> &columns) {
270263
vector<oracle::occi::MetaData> metadata = rs->getColumnListMetaData();
271264
for (vector<oracle::occi::MetaData>::iterator iterator = metadata.begin(), end = metadata.end(); iterator != end; ++iterator) {
272265
oracle::occi::MetaData metadata = *iterator;
@@ -308,14 +301,14 @@ void Connection::CreateColumnsFromResultSet(oracle::occi::ResultSet* rs, vector<
308301
ostringstream message;
309302
message << "CreateColumnsFromResultSet: Unhandled oracle data type: " << type;
310303
delete col;
311-
throw NodeOracleException(message.str());
312-
break;
304+
baton->error = new std::string(message.str());
305+
return;
313306
}
314307
columns.push_back(col);
315308
}
316309
}
317310

318-
row_t* Connection::CreateRowFromCurrentResultSetRow(oracle::occi::ResultSet* rs, vector<column_t*> &columns) {
311+
row_t* Connection::CreateRowFromCurrentResultSetRow(oracle::occi::ResultSet* rs, ExecuteBaton* baton, vector<column_t*> &columns) {
319312
row_t* row = new row_t();
320313
int colIndex = 1;
321314
for (vector<column_t*>::iterator iterator = columns.begin(), end = columns.end(); iterator != end; ++iterator, colIndex++) {
@@ -345,8 +338,9 @@ row_t* Connection::CreateRowFromCurrentResultSetRow(oracle::occi::ResultSet* rs,
345338
default:
346339
ostringstream message;
347340
message << "CreateRowFromCurrentResultSetRow: Unhandled type: " << col->type;
348-
throw NodeOracleException(message.str());
349-
break;
341+
baton->error = new std::string(message.str());
342+
delete row;
343+
return NULL;
350344
}
351345
}
352346
}
@@ -401,12 +395,14 @@ void Connection::EIO_Execute(uv_work_t* req) {
401395
oracle::occi::ResultSet* rs = NULL;
402396
try {
403397
if(! baton->connection->m_connection) {
404-
throw NodeOracleException("Connection already closed");
398+
baton->error = new std::string("Connection already closed");
399+
return;
405400
}
406401
stmt = baton->connection->m_connection->createStatement(baton->sql);
407402
stmt->setAutoCommit(baton->connection->m_autoCommit);
408403
if (baton->connection->m_prefetchRowCount > 0) stmt->setPrefetchRowCount(baton->connection->m_prefetchRowCount);
409-
int outputParam = SetValuesOnStatement(stmt, baton->values);
404+
int outputParam = SetValuesOnStatement(stmt, baton);
405+
if (baton->error) goto cleanup;
410406

411407
int status = stmt->execute();
412408
if(status == oracle::occi::Statement::UPDATE_COUNT_AVAILABLE) {
@@ -430,10 +426,12 @@ void Connection::EIO_Execute(uv_work_t* req) {
430426
break;
431427
case OutParam::OCCICURSOR:
432428
rs = stmt->getCursor(output->index);
433-
CreateColumnsFromResultSet(rs, output->columns);
429+
CreateColumnsFromResultSet(rs, baton, output->columns);
430+
if (baton->error) goto cleanup;
434431
output->rows = new vector<row_t*>();
435432
while(rs->next()) {
436-
row_t* row = CreateRowFromCurrentResultSetRow(rs, output->columns);
433+
row_t* row = CreateRowFromCurrentResultSetRow(rs, baton, output->columns);
434+
if (baton->error) goto cleanup;
437435
output->rows->push_back(row);
438436
}
439437
break;
@@ -456,31 +454,32 @@ void Connection::EIO_Execute(uv_work_t* req) {
456454
{
457455
ostringstream oss;
458456
oss << "Unknown OutParam type: " << output->type;
459-
throw NodeOracleException(oss.str());
457+
baton->error = new std::string(oss.str());
458+
goto cleanup;
460459
}
461460
}
462461
}
463462
}
464463
} else if(status == oracle::occi::Statement::RESULT_SET_AVAILABLE) {
465464
rs = stmt->getResultSet();
466-
CreateColumnsFromResultSet(rs, baton->columns);
465+
CreateColumnsFromResultSet(rs, baton, baton->columns);
466+
if (baton->error) goto cleanup;
467467
baton->rows = new vector<row_t*>();
468468

469469
while(rs->next()) {
470-
row_t* row = CreateRowFromCurrentResultSetRow(rs, baton->columns);
470+
row_t* row = CreateRowFromCurrentResultSetRow(rs, baton, baton->columns);
471+
if (baton->error) goto cleanup;
471472
baton->rows->push_back(row);
472473
}
473474
}
474475
} catch(oracle::occi::SQLException &ex) {
475476
baton->error = new string(ex.getMessage());
476-
} catch(NodeOracleException &ex) {
477-
baton->error = new string(ex.getMessage());
478477
} catch (const exception& ex) {
479478
baton->error = new string(ex.what());
480479
} catch (...) {
481480
baton->error = new string("Unknown Error");
482481
}
483-
482+
cleanup:
484483
if(stmt && rs) {
485484
stmt->closeResultSet(rs);
486485
rs = NULL;
@@ -533,7 +532,7 @@ Local<Date> OracleTimestampToV8Date(oracle::occi::Timestamp* d) {
533532
return date;
534533
}
535534

536-
Local<Object> Connection::CreateV8ObjectFromRow(vector<column_t*> columns, row_t* currentRow) {
535+
Local<Object> Connection::CreateV8ObjectFromRow(ExecuteBaton* baton, vector<column_t*> columns, row_t* currentRow) {
537536
Local<Object> obj = Object::New();
538537
uint32_t colIndex = 0;
539538
for (vector<column_t*>::iterator iterator = columns.begin(), end = columns.end(); iterator != end; ++iterator, colIndex++) {
@@ -639,21 +638,22 @@ Local<Object> Connection::CreateV8ObjectFromRow(vector<column_t*> columns, row_t
639638
default:
640639
ostringstream oss;
641640
oss << "CreateV8ObjectFromRow: Unhandled type: " << col->type;
642-
throw NodeOracleException(oss.str());
643-
break;
641+
baton->error = new std::string(oss.str());
642+
return obj;
644643
}
645644
}
646645
}
647646
return obj;
648647
}
649648

650-
Local<Array> Connection::CreateV8ArrayFromRows(vector<column_t*> columns, vector<row_t*>* rows) {
649+
Local<Array> Connection::CreateV8ArrayFromRows(ExecuteBaton* baton, vector<column_t*> columns, vector<row_t*>* rows) {
651650
size_t totalRows = rows->size();
652651
Local<Array> retRows = Array::New(totalRows);
653652
uint32_t index = 0;
654653
for (vector<row_t*>::iterator iterator = rows->begin(), end = rows->end(); iterator != end; ++iterator, index++) {
655654
row_t* currentRow = *iterator;
656-
Local<Object> obj = CreateV8ObjectFromRow(columns, currentRow);
655+
Local<Object> obj = CreateV8ObjectFromRow(baton, columns, currentRow);
656+
if (baton->error) return retRows;
657657
retRows->Set(index, obj);
658658
}
659659
return retRows;
@@ -669,11 +669,6 @@ void Connection::EIO_AfterExecute(uv_work_t* req, int status) {
669669
Handle<Value> argv[2];
670670
handleResult(baton, argv);
671671
node::MakeCallback(Context::GetCurrent()->Global(), baton->callback, 2, argv);
672-
} catch(NodeOracleException &ex) {
673-
Handle<Value> argv[2];
674-
argv[0] = Exception::Error(String::New(ex.getMessage().c_str()));
675-
argv[1] = Undefined();
676-
node::MakeCallback(Context::GetCurrent()->Global(), baton->callback, 2, argv);
677672
} catch(const exception &ex) {
678673
Handle<Value> argv[2];
679674
argv[0] = Exception::Error(String::New(ex.what()));
@@ -686,12 +681,14 @@ void Connection::EIO_AfterExecute(uv_work_t* req, int status) {
686681

687682
void Connection::handleResult(ExecuteBaton* baton, Handle<Value> (&argv)[2]) {
688683
if(baton->error) {
684+
failed:
689685
argv[0] = Exception::Error(String::New(baton->error->c_str()));
690686
argv[1] = Undefined();
691687
} else {
692688
argv[0] = Undefined();
693689
if(baton->rows) {
694-
argv[1] = CreateV8ArrayFromRows(baton->columns, baton->rows);
690+
argv[1] = CreateV8ArrayFromRows(baton, baton->columns, baton->rows);
691+
if (baton->error) goto failed; // delete argv[1] ??
695692
} else {
696693
Local<Object> obj = Object::New();
697694
obj->Set(String::New("updateCount"), Integer::New(baton->updateCount));
@@ -721,7 +718,8 @@ void Connection::handleResult(ExecuteBaton* baton, Handle<Value> (&argv)[2]) {
721718
obj->Set(String::New(returnParam.c_str()), Number::New(output->floatVal));
722719
break;
723720
case OutParam::OCCICURSOR:
724-
obj->Set(String::New(returnParam.c_str()), CreateV8ArrayFromRows(output->columns, output->rows));
721+
obj->Set(String::New(returnParam.c_str()), CreateV8ArrayFromRows(baton, output->columns, output->rows));
722+
if (baton->error) goto failed;
725723
break;
726724
case OutParam::OCCICLOB:
727725
{
@@ -771,7 +769,8 @@ void Connection::handleResult(ExecuteBaton* baton, Handle<Value> (&argv)[2]) {
771769
{
772770
ostringstream oss;
773771
oss << "Unknown OutParam type: " << output->type;
774-
throw NodeOracleException(oss.str());
772+
baton->error = new std::string(oss.str());
773+
goto failed;
775774
}
776775
}
777776
}
@@ -794,11 +793,11 @@ Handle<Value> Connection::ExecuteSync(const Arguments& args) {
794793

795794
String::Utf8Value sqlVal(sql);
796795

797-
ExecuteBaton* baton;
798-
try {
799-
baton = new ExecuteBaton(connection, *sqlVal, &values, NULL);
800-
} catch(NodeOracleException &ex) {
801-
return ThrowException(Exception::Error(String::New(ex.getMessage().c_str())));
796+
ExecuteBaton* baton = new ExecuteBaton(connection, *sqlVal, &values, NULL);
797+
if (baton->error) {
798+
Local<String> message = String::New(baton->error->c_str());
799+
delete baton;
800+
return scope.Close(ThrowException(Exception::Error(message)));
802801
}
803802

804803
uv_work_t* req = new uv_work_t();

src/connection.h

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
#include <occi.h>
1111
#include <oro.h>
1212
#include "utils.h"
13-
#include "nodeOracleException.h"
1413
#include "executeBaton.h"
1514

1615
using namespace node;
@@ -44,11 +43,11 @@ class Connection : ObjectWrap {
4443
oracle::occi::Environment* getEnvironment() { return m_environment; }
4544

4645
private:
47-
static int SetValuesOnStatement(oracle::occi::Statement* stmt, std::vector<value_t*> &values);
48-
static void CreateColumnsFromResultSet(oracle::occi::ResultSet* rs, std::vector<column_t*> &columns);
49-
static row_t* CreateRowFromCurrentResultSetRow(oracle::occi::ResultSet* rs, std::vector<column_t*> &columns);
50-
static Local<Array> CreateV8ArrayFromRows(std::vector<column_t*> columns, std::vector<row_t*>* rows);
51-
static Local<Object> CreateV8ObjectFromRow(std::vector<column_t*> columns, row_t* currentRow);
46+
static int SetValuesOnStatement(oracle::occi::Statement* stmt, ExecuteBaton* baton);
47+
static void CreateColumnsFromResultSet(oracle::occi::ResultSet* rs, ExecuteBaton* baton, std::vector<column_t*> &columns);
48+
static row_t* CreateRowFromCurrentResultSetRow(oracle::occi::ResultSet* rs, ExecuteBaton* baton, std::vector<column_t*> &columns);
49+
static Local<Array> CreateV8ArrayFromRows(ExecuteBaton* baton, std::vector<column_t*> columns, std::vector<row_t*>* rows);
50+
static Local<Object> CreateV8ObjectFromRow(ExecuteBaton* baton, std::vector<column_t*> columns, row_t* currentRow);
5251
static void handleResult(ExecuteBaton* baton, Handle<Value> (&argv)[2]);
5352

5453
oracle::occi::Connection* m_connection;

src/executeBaton.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11

22
#include "executeBaton.h"
33
#include "outParam.h"
4-
#include "nodeOracleException.h"
54
#include "connection.h"
65
#include <iostream>
76
using namespace std;
@@ -13,8 +12,8 @@ ExecuteBaton::ExecuteBaton(Connection* connection, const char* sql, v8::Local<v8
1312
this->callback = Persistent<Function>::New(*callback);
1413
}
1514
this->outputs = new std::vector<output_t*>();
16-
CopyValuesToBaton(this, values);
1715
this->error = NULL;
16+
CopyValuesToBaton(this, values);
1817
}
1918

2019
ExecuteBaton::~ExecuteBaton() {
@@ -130,8 +129,9 @@ void ExecuteBaton::CopyValuesToBaton(ExecuteBaton* baton, v8::Local<v8::Array>*
130129
else {
131130
//XXX leaks new value on error
132131
std::ostringstream message;
133-
message << "CopyValuesToBaton: Unhandled value type";
134-
throw NodeOracleException(message.str());
132+
message << "CopyValuesToBaton: Unhandled value type: " << (val->IsUndefined() ? "undefined" : "unknown");
133+
baton->error = new std::string(message.str());
134+
return;
135135
}
136136

137137
}

src/nodeOracleException.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
#define _nodeOracleException_h_
44

55
#include <string>
6-
76
class NodeOracleException {
87
public:
98
NodeOracleException(std::string message) : m_message(message) {

src/outParam.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11

22
#include "outParam.h"
3-
#include "nodeOracleException.h"
43
#include <iostream>
54
using namespace std;
65

@@ -62,7 +61,7 @@ Handle<Value> OutParam::New(const Arguments& args) {
6261
break;
6362
}
6463
default:
65-
throw NodeOracleException("Unhandled OutPram type!");
64+
return scope.Close(ThrowException(Exception::Error(String::New("Unhandled OutPram type!"))));
6665
}
6766
}
6867
}

0 commit comments

Comments
 (0)