Error Handling
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:
PRL_FAILED
|
Returns True if the return value indicates failure, or False if the return value indicates success.
|
PRL_SUCCEEDED
|
Returns True if the return value indicates success, or False if the return value indicates failure.
|
prl_result_to_string
|
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(resWaitForCreateDir));
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;
}
|