Synchronous Functions
All synchronous Parallels C API functions return
PRL_RESULT
, which is an integer indicating success or failure of the operation.
Error Codes for Asynchronous Functions
All asynchronous functions return
PRL_HANDLE
. The error code (return value) in this case can be extracted with
PrlJob_GetRetCode
after the asynchronous job has finished.
Analyzing Return Values
Parallels C API provides the following macros to work with error codes:
|
Returns True if the return value indicates failure, or False if the return value indicates success. |
|
Returns True if the return value indicates success, or False if the return value indicates failure. |
|
Returns a string representation of the error code. |
The following code snippet attempts to create a directory on the host and analyzes the return value (error code) of asynchronous function
PrlSrv_CreateDir
.
// Attempt to create directory /tmp/TestDir on the host.
char *szRemoteDir = "/tmp/TestDir";
hJob = PrlSrv_FsCreateDir(hServer, szRemoteDir);
// Wait for a maximum of 5 seconds for asynchronous
// function PrlSrv_FsCreateDir to complete.
PRL_RESULT resWaitForCreateDir = PrlJob_Wait(hJob, 5000);
if (PRL_FAILED(resWaitForCreateDir))
{
fprintf(stderr, "PrlJob_Wait for PrlSvr_FsCreateDir failed with error: %s\n",
prl_result_to_string(ret));
PrlHandle_Free(hJob);
return -1;
}
// Extract the asynchronous function return code.
PrlJob_GetRetCode(hJob, &nJobResult);
if (PRL_FAILED(nJobResult))
{
fprintf(stderr, "Error creating directory %s. Error returned: %s\n",
szRemoteDir, prl_result_to_string(nJobResult));
PrlHandle_Free(hJob);
return -1;
}
PrlHandle_Free( hJob );
printf( "Remote directory %s was successfully created.\n", szRemoteDir );
Descriptive Error Strings
Descriptive error messages can sometimes be obtained using the
PrlJob_GetError
function. This function will return a handle to an object of type
PHT_EVENT
. In cases where
PrlJob_GetError
is unable to return error information,
PrlApi_GetResultDescription
can be used. Although it is possible to avoid using
PrlJob_GetError
and use
PrlJob_GetResultDescription
instead, it is recommended to first use
PrlJob_GetError
, and if this doesn't return additional descriptive error information then use
PrlApi_GetResultDescription
. The reason is that sometimes errors contain dynamic parameters. The following example demonstrates how to obtain descriptive error information:
PrlJob_GetRetCode(hJob,
&nJobResult);
PRL_CHAR szErrBuff[1024];
PRL_UINT32 nErrBuffSize = sizeof(szErrBuff);
PRL_HANDLE hError = PRL_INVALID_HANDLE;
PRL_RESULT ret = PrlJob_GetError(hJob,
&hError);
// Check if additional error information is available.
if (PRL_SUCCEEDED(ret)) // Additional error information is available.
{
// Additional error information is available.
ret = PrlEvent_GetErrString(hError, PRL_FALSE, PRL_FALSE, szErrBuff,
&nErrBuffSize);
if (PRL_FAILED(ret))
{
printf(
"PrlEvent_GetErrString returned error: %.8x %s\n",
ret, prl_result_to_string(ret));
}
else
{
// Extra error information is available, display it.
printf(
"Error returned: %.8x %s\n", nJobResult, prl_result_to_string(nJobResult));
printf(
"Descriptive error: %s\n", szErrBuff);
}
}
else
{
// No additional error information available, so use PrlApi_GetResultDescription.
ret = PrlApi_GetResultDescription(nJobResult, PRL_FALSE, PRL_FALSE, szErrBuff,
&nErrBuffSize);
if (PRL_FAILED(ret))
{
printf(
"PrlApi_GetResultDescription returned error: %s\n",
prl_result_to_string(ret));
}
else
{
printf(
"Error returned: %.8x %s\n", nJobResult, prl_result_to_string(nJobResult));
printf(
"Descriptive error: %s\n", szErrBuff);
}
}
// Free handles, return the error code.
PrlHandle_Free(hJob);
PrlHandle_Free(hError);
return nJobResult;
}