Add new attributes for Oracle error number and offset for Oracle client errors
This commit is contained in:
parent
9f1a74b014
commit
dca2b038c5
25
doc/api.md
25
doc/api.md
|
@ -21,6 +21,9 @@ limitations under the License.
|
|||
- 1.1 [Getting Started with Node-oracledb](#getstarted)
|
||||
2. [Errors](#errorobj)
|
||||
- 2.1 [Error Properties](#properror)
|
||||
- 2.1.1 [`errorNum`](#properrerrornum)
|
||||
- 2.1.2 [`message`](#properrmessage)
|
||||
- 2.1.3 [`offset`](#properroffset)
|
||||
3. [Oracledb Class](#oracledbclass)
|
||||
- 3.1 [Oracledb Constants](#oracledbconstants)
|
||||
- 3.1.1 [Query `outFormat` Constants](#oracledbconstantsoutformat)
|
||||
|
@ -316,7 +319,18 @@ ignored.
|
|||
|
||||
### <a name="properror"></a> 2.1 Error Properties
|
||||
|
||||
The *Error* object contains a message property.
|
||||
The *Error* object contains `errorNum`, `message` and `offset` properties.
|
||||
|
||||
#### <a name="properrerrornum"></a> 2.1.1 `errorNum`
|
||||
|
||||
```
|
||||
Number errorNum
|
||||
```
|
||||
|
||||
The Oracle error number. If the error is not from Oracle, this value
|
||||
is undefined.
|
||||
|
||||
#### <a name="properrmessage"></a> 2.1.2 `message`
|
||||
|
||||
```
|
||||
String message
|
||||
|
@ -343,6 +357,15 @@ ORA-06550: line 1, column 7:
|
|||
PL/SQL: Statement ignored
|
||||
```
|
||||
|
||||
#### <a name="properroffset"></a> 2.1.3 `offset`
|
||||
|
||||
```
|
||||
Number offset
|
||||
```
|
||||
|
||||
The character offset into the SQL text that resulted in the Oracle
|
||||
error. The value may be `0` in non-SQL contexts. If the error is not
|
||||
from Oracle, this value is undefined.
|
||||
|
||||
## <a name="oracledbclass"></a> 3. Oracledb Class
|
||||
|
||||
|
|
|
@ -300,6 +300,7 @@ void njsBaton::AsyncAfterWorkCallback(uv_work_t *req, int status)
|
|||
Nan::TryCatch tc;
|
||||
Local<Value> *callbackArgs = new Local<Value>[baton->numCallbackArgs];
|
||||
unsigned int i, numCallbackArgs = baton->numCallbackArgs;
|
||||
Local<Object> errorObj;
|
||||
|
||||
// set all parameters but the first as undefined; the first parameter is
|
||||
// always expected to be the error and should be null
|
||||
|
@ -316,6 +317,14 @@ void njsBaton::AsyncAfterWorkCallback(uv_work_t *req, int status)
|
|||
if (!baton->error.empty()) {
|
||||
callbackArgs[0] = v8::Exception::Error(Nan::New<v8::String>(
|
||||
baton->error).ToLocalChecked());
|
||||
if (baton->dpiError) {
|
||||
errorObj = callbackArgs[0]->ToObject();
|
||||
Nan::Set(errorObj,
|
||||
Nan::New<v8::String>("errorNum").ToLocalChecked(),
|
||||
Nan::New<v8::Number>(baton->errorInfo.code));
|
||||
Nan::Set(errorObj, Nan::New<v8::String>("offset").ToLocalChecked(),
|
||||
Nan::New<v8::Number>(baton->errorInfo.offset));
|
||||
}
|
||||
for (i = 1; i < numCallbackArgs; i++)
|
||||
callbackArgs[i] = Nan::Undefined();
|
||||
}
|
||||
|
@ -350,7 +359,13 @@ void njsBaton::AsyncAfterWorkCallback(uv_work_t *req, int status)
|
|||
//-----------------------------------------------------------------------------
|
||||
void njsBaton::GetDPIError(void)
|
||||
{
|
||||
error = njsOracledb::GetDPIError();
|
||||
dpiContext_getError(njsOracledb::GetDPIContext(), &errorInfo);
|
||||
if (errorInfo.code == 1406)
|
||||
error = njsMessages::Get(errInsufficientBufferForBinds);
|
||||
else {
|
||||
error = std::string(errorInfo.message, errorInfo.messageLength);
|
||||
dpiError = true;
|
||||
}
|
||||
ClearAsyncData();
|
||||
}
|
||||
|
||||
|
|
|
@ -288,6 +288,8 @@ public:
|
|||
char *bufferPtr;
|
||||
uint64_t lobOffset;
|
||||
uint64_t lobAmount;
|
||||
dpiErrorInfo errorInfo;
|
||||
bool dpiError;
|
||||
njsCommon *callingObj;
|
||||
Nan::Persistent<Object> jsCallingObj;
|
||||
Nan::Persistent<Object> jsOracledb;
|
||||
|
@ -306,7 +308,7 @@ public:
|
|||
fetchAsBufferTypes(NULL), protoILob(NULL), externalAuth(false),
|
||||
getRS(false), autoCommit(false), extendedMetaData(false),
|
||||
isReturning(false), isPLSQL(false), bufferSize(0), bufferPtr(NULL),
|
||||
lobOffset(0), lobAmount(0) {
|
||||
lobOffset(0), lobAmount(0), dpiError(false) {
|
||||
this->jsCallback.Reset(callback);
|
||||
this->jsCallingObj.Reset(callingObj);
|
||||
this->callingObj = Nan::ObjectWrap::Unwrap<njsCommon>(callingObj);
|
||||
|
|
|
@ -1290,10 +1290,8 @@ void njsConnection::SetTextAttribute(Nan::NAN_SETTER_ARGS_TYPE args,
|
|||
return;
|
||||
}
|
||||
v8::String::Utf8Value utfstr(value->ToString());
|
||||
if ((*setter)(connection->dpiConnHandle, *utfstr, utfstr.length()) < 0) {
|
||||
std::string errMsg = njsOracledb::GetDPIError();
|
||||
Nan::ThrowError(errMsg.c_str());
|
||||
}
|
||||
if ((*setter)(connection->dpiConnHandle, *utfstr, utfstr.length()) < 0)
|
||||
njsOracledb::ThrowDPIError();
|
||||
}
|
||||
|
||||
|
||||
|
@ -1705,8 +1703,7 @@ NAN_GETTER(njsConnection::GetStmtCacheSize)
|
|||
}
|
||||
uint32_t cacheSize;
|
||||
if (dpiConn_getStmtCacheSize(connection->dpiConnHandle, &cacheSize) < 0) {
|
||||
std::string errMsg = njsOracledb::GetDPIError();
|
||||
Nan::ThrowError(errMsg.c_str());
|
||||
njsOracledb::ThrowDPIError();
|
||||
return;
|
||||
}
|
||||
info.GetReturnValue().Set(cacheSize);
|
||||
|
@ -1804,8 +1801,7 @@ NAN_GETTER(njsConnection::GetOracleServerVersion)
|
|||
const char *releaseString;
|
||||
if (dpiConn_getServerVersion(connection->dpiConnHandle, &releaseString,
|
||||
&releaseStringLength, &versionInfo) < 0) {
|
||||
std::string errMsg = njsOracledb::GetDPIError();
|
||||
Nan::ThrowError(errMsg.c_str());
|
||||
njsOracledb::ThrowDPIError();
|
||||
return;
|
||||
}
|
||||
uint32_t oracleServerVersion =
|
||||
|
|
|
@ -208,8 +208,7 @@ NAN_METHOD(njsOracledb::New)
|
|||
dpiVersionInfo versionInfo;
|
||||
|
||||
if (dpiContext_getClientVersion(globalDPIContext, &versionInfo) < 0) {
|
||||
std::string errMsg = GetDPIError();
|
||||
Nan::ThrowError(errMsg.c_str());
|
||||
ThrowDPIError();
|
||||
return;
|
||||
}
|
||||
njsOracledb *oracledb = new njsOracledb();
|
||||
|
@ -762,8 +761,7 @@ NAN_GETTER(njsOracledb::GetOracleClientVersion)
|
|||
return;
|
||||
|
||||
if (dpiContext_getClientVersion(globalDPIContext, &versionInfo) < 0) {
|
||||
std::string errMsg = GetDPIError();
|
||||
Nan::ThrowError(errMsg.c_str());
|
||||
ThrowDPIError();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1012,17 +1010,25 @@ void njsOracledb::SetFetchAsBufferTypesOnBaton(njsBaton *baton) const
|
|||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// njsOracledb::GetDPIError()
|
||||
// Gets the error information from DPI and returns it.
|
||||
// njsOracledb::ThrowDPIError()
|
||||
// Gets the error information from ODPI-C and throws an exception.
|
||||
//-----------------------------------------------------------------------------
|
||||
std::string njsOracledb::GetDPIError(void)
|
||||
void njsOracledb::ThrowDPIError(void)
|
||||
{
|
||||
dpiErrorInfo errorInfo;
|
||||
Local<Value> exception;
|
||||
Local<Object> errorObj;
|
||||
std::string errMsg;
|
||||
|
||||
dpiContext_getError(globalDPIContext, &errorInfo);
|
||||
if (errorInfo.code == 1406)
|
||||
return njsMessages::Get(errInsufficientBufferForBinds);
|
||||
return std::string(errorInfo.message, errorInfo.messageLength);
|
||||
errMsg = std::string(errorInfo.message, errorInfo.messageLength);
|
||||
exception = Nan::Error(errMsg.c_str());
|
||||
errorObj = exception->ToObject();
|
||||
Nan::Set(errorObj, Nan::New<v8::String>("errorNum").ToLocalChecked(),
|
||||
Nan::New<v8::Number>(errorInfo.code));
|
||||
Nan::Set(errorObj, Nan::New<v8::String>("offset").ToLocalChecked(),
|
||||
Nan::New<v8::Number>(errorInfo.offset));
|
||||
Nan::ThrowError(exception);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -124,8 +124,8 @@ public:
|
|||
njsErrorType GetInvalidErrorType() const { return errSuccess; }
|
||||
void SetFetchAsStringTypesOnBaton(njsBaton *baton) const;
|
||||
void SetFetchAsBufferTypesOnBaton(njsBaton *baton) const;
|
||||
static std::string GetDPIError(void);
|
||||
static dpiContext *GetDPIContext() { return globalDPIContext; }
|
||||
static void ThrowDPIError(void);
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
@ -216,8 +216,7 @@ NAN_GETTER(njsPool::GetConnectionsOpen)
|
|||
}
|
||||
uint32_t value;
|
||||
if (dpiPool_getOpenCount(pool->dpiPoolHandle, &value) < 0) {
|
||||
std::string errMsg = njsOracledb::GetDPIError();
|
||||
Nan::ThrowError(errMsg.c_str());
|
||||
njsOracledb::ThrowDPIError();
|
||||
return;
|
||||
}
|
||||
info.GetReturnValue().Set(value);
|
||||
|
@ -239,8 +238,7 @@ NAN_GETTER(njsPool::GetConnectionsInUse)
|
|||
}
|
||||
uint32_t value;
|
||||
if (dpiPool_getBusyCount(pool->dpiPoolHandle, &value) < 0) {
|
||||
std::string errMsg = njsOracledb::GetDPIError();
|
||||
Nan::ThrowError(errMsg.c_str());
|
||||
njsOracledb::ThrowDPIError();
|
||||
return;
|
||||
}
|
||||
info.GetReturnValue().Set(value);
|
||||
|
|
Loading…
Reference in New Issue