Error Handling   

<<< Introduction To Error Handling Chapters Signal Handling >>>

Contents

[back to top]


120.1 Introduction

This chapter describes how to handle errors and other failure status codes returned by Parasolid functions. It is essential that your application intercepts and deals with these errors.

A complete list of all Parasolid error codes, together with descriptions of each error code, and information about which functions can raise the error, can be found in the PK Interface Programming Reference Manual. Common errors returned by a function are listed as “specific errors” in the documentation for that function, although this list is not exhaustive. Further frustrum-specific error information is available from the Downward Interfaces manual.

For examples of handling PK errors, see the code examples in the C++\Code Examples\Application support\Error Handling folder, located in example_applications in your Parasolid installation folder.

 

Note: None of these strategies is generally applicable to KI routines. For information on handling errors from these routines (which are indicated by a non-zero value for ifail ) see Section 1.5, “Error returns” of the KI Programming Reference Manual. Further information is available from Appendix B, “Kernel Interface Error Codes” in this manual.

 

Related Topics:

[back to top]


120.2 PK errors

There are two primary decisions to make when deciding how to handle PK errors:

Your application can register a particular function, known as an error handler, with Parasolid. This function is supplied by you and will be called whenever an error occurs, to perform certain recovery tasks. Parasolid automatically invokes this error-handling function just before returning from a failing PK function. If control is then passed back to the application (through the failing PK function), the values of any return arguments of the PK function are undefined.

In addition, your application can choose whether to throw an exception when it encounters an error, via the try/throw/catch statements in C++ (or the equivalent setjmp/longjmp functions in C). If your application uses a registered error handler combined with exceptions, it does not need to check the return status of each PK function before proceeding.

Whichever strategy you choose, the same recovery action needs to be taken at some point. This action depends on the severity of the error, as described in Section 120.2.2, “Error severity”.

 

Note: For the purposes of this chapter, the try/throw/catch statements (C++) and setjmp/longjmp functions (C) are treated as equivalent, and our examples illustrating the use of try/throw/catch should serve for both. Situations in C++ applications that require the use of setjmp/longjmp instead of try/throw/catch are beyond the scope of this manual.

120.2.1 Simplified outline of a Parasolid application

To provide a context for comparing ways of handling PK errors, a simplified outline of a C++ driver routine for an interactive Parasolid application is given in Figure 120-1. Execution proceeds in an infinite loop that starts by waiting for an instruction from the user. Once given, the instruction is processed according to its type, which may invoke one or more calls to Parasolid functions.

The code for processing the instructions is wrapped in a try statement, with corresponding catch blocks to deal with any types of error that arise (from Parasolid or otherwise). These blocks inform the user that the instruction has not been carried out, and make sure that the application is ready to receive the next instruction: this could be to try the previous instruction again, with different input data.

 

while (true)
{
	// await input from the keyboard/mouse/etc.
	myApp->getNextInstruction( &instruction );
	// process instruction
	try
	{
		switch (instruction.type)
		{
		case i_type_1:
		...
		
		case i_type_n:
	// processing instruction initiates (at some point) 
//a sequence of (related) PK functions
	
			... // PK function calls happen here
	
			// deal with any errors (from PK or otherwise)
			if ( myApp->isError() )
			{
				errorTypeN error = myApp->getError();
				throw error;
			}
			break;
		
		...
		}
	}
	
	catch (errorType1 error)
	{
	// take appropriate recovery action and 
//prepare to receive the next instruction
		...
	}
	
	catch (errorType2 error)
	{
		...
	}
	
	...
}

Figure 120-1 Simplified outline of the main loop in a Parasolid application

120.2.2 Error severity

PK errors (i.e., when a function returns a value other than PK_ERROR_no_errors) can be classified by their severity, which is either mild, serious or fatal. The consequences of the error, and steps necessary for recovery, depend on the severity, as described in the following table.

 

Severity

Current state

Required action

Mild

The operation failed but the parts involved were not altered.

Your application can continue as normal.

Serious

The parts involved in the operation may have been altered, and may be invalid as a result. The rest of the Parasolid session is intact.

Your application should roll back to a valid state of the model. If rolling back has not been implemented, it should stop and restart the Parasolid session, and re-register the frustrum and the delta frustrum.

Fatal

The Parasolid session has been corrupted; rolling back, if implemented, will not be effective.

Your application should stop and restart the Parasolid session, and re-register the frustrum and the delta frustrum. Occasionally, it may be necessary for the application to exit.

If your application does not carry out the necessary action after a serious or fatal error, data structures may become corrupt, leading to run-time errors at a later stage. You are therefore strongly advised to implement rollback functionality in your application, in order to restore a session after serious errors: see Chapter 97, “Rollback”, for details. Note that if you have more than one partition in your session, you should roll back every partition that contains entities affected by the error.

If you are dealing with multiple threads in your application and a serious error occurs in one or more of the threads you should call PK_THREAD_ask_exclusion to assess whether the error needs to be handled. You can then either roll back or use PK_THREAD_clear_exclusion. See Section 113.6.1, “Excluding application threads after a serious or fatal error” for information on PK_THREAD_clear_exclusion.

 

Warning: Certain error codes may denote a mild or a serious error, depending on the circumstances in which they are raised. It is therefore essential not to rely on the error code alone but to check the severity for an accurate diagnosis of the problem.

120.2.3 Error-handling strategy

The ways to handle errors described in this section are:

You register an error-handling function with Parasolid by calling PK_ERROR_register_callbacks. Your error handler must receive a pointer to a PK_ERROR_sf_t structure and have the return type PK_ERROR_code_t, although it need not necessarily return a value, as this is not used by Parasolid. The PK_ERROR_sf_t structure contains details of the error such as the name of the failing function, the error code, and the severity of the error. For more details, see Section 120.2.5, “PK_ERROR functions and their use” and also the error-handling code examples in the Example Application within the Jumpstart Kit.

Note that an error handler that uses exceptions does not have to throw an exception for every type of error. For example, you can design it to return to the failing PK function for certain errors and throw an exception for the rest.

 

Warning: Your error handler should not attempt to alter any details of the current error (by modifying the PK_ERROR_sf_t structure, or returning a different error code): Parasolid stores this information separately, and any such alterations have no effect.

The strategies here also apply to re-entrant function calls, where a PK function is called from the GO or some other application function that has itself been called from Parasolid. They work in the same way, although any exceptions must be thrown back to a point outside of any PK function calls; they must not be thrown to functions called from Parasolid, as this could leave the PK kernel in an inconsistent state.

When dealing with multiple threads in an application, PK_THREAD_xxx functions should be used instead of PK_SESSION_xxx or PK_ERROR_xxx functions. For example, you should use PK_THREAD_ask_last_error in preference to PK_ERROR_ask_last. See Section 113.2, “How to set up and use application threads”for a list of these functions.

 

Warning: Calling PK functions other than PK_SESSION_tidy within an error handler that returns to your application via Parasolid may lead to unpredictable results.

120.2.3.1 Not registering an error handler

The example code of Figure 120-2 and Figure 120-3 illustrates handling errors without registering an error handler.

A sequence of PK function calls takes place. After each call, the application checks the return status of the function before the next call is made. If an error is encountered somewhere, the subsequent if statements ensure that no further PK function calls are made until the error is dealt with. In the event of an error, the function PK_ERROR_ask_last is called to obtain the relevant details (see Section 120.2.5, “PK_ERROR functions and their use”), which are recorded by the application for later use (see Figure 120-1). The application then calls its own function, handlePKError, which has not been registered with Parasolid.

 

	// call sequence of (related) PK functions
	PK_ERROR_t error = PK_XXX_fun_1( arg1, ..., argn );
	// check the error return code each time before continuing
	if (error == PK_ERROR_no_errors)
		error = PK_XXX_fun_2( arg1, ..., argm );
	if (error == PK_ERROR_no_errors)
		error = PK_XXX_fun_3( arg1, ..., argr );
	...
	
	// perform error handling after PK calls
	if (error != PK_ERROR_no_errors)
	{
		PK_LOGICAL_t was_error;
		PK_ERROR_sf_t error_sf;
		// get details of the error
		PK_THREAD_ask_last_error( &was_error, &error_sf );
	// set error information for the application and 
//take appropriate action
		myApp->setErrorStatus( true );
		myApp->setError( “PK”, error_sf.severity, ... );
		myApp->handlePKError( &error_sf );
	}

Figure 120-2 Sequence of PK calls with no registered error handler

The function handlePKError performs certain PK-specific recovery tasks according to the severity of the error, as described in Section 120.2.2, “Error severity”, and also any application-specific tidying up that needs to be done. Note that for mild and serious errors, the failing operation might be repeated (with different data); hence further action to prepare for this would be taken by the application in the main loop of the code (see Figure 120-1).

 

void myApp::handlePKError( PK_ERROR_sf_t* error_sf )
{
	if (error_sf->severity == PK_ERROR_mild)
	{
		// warn user of a mild error
		Message( "Mild error in Parasolid function %s", error_sf->function );
		... // perform any further application-specific clean-up tasks
	}
	else if (error_sf->severity == PK_ERROR_serious)
	{
		// warn user of a serious error
		Message( "Serious error in Parasolid function %s", error_sf->function );
	// roll back the current partition (and any other affected partitions)
		PK_SESSION_ask_curr_partition( &partition );
		PK_PARTITION_ask_pmark( partition, &pmark1, ... );
		PK_PMARK_goto_2
( pmark1, &n_new, &new_entities, ... );
		// free allocated memory where necessary
		if (n_new) PK_MEMORY_free( new_entities );
		... // perform any further application-specific clean-up tasks
	}
	else if (error_sf->severity == PK_ERROR_fatal)
	{
		// warn user of a fatal error
		Message( "Fatal error in Parasolid function %s", error_sf->function );
		// stop the current session
		PK_SESSION_stop();
	 //call application function containing PK calls to start a new session 
//
and re-register the frustrum and delta frustrum
		restartParasolid();
		... // perform any further application-specific clean-up tasks
	}
}

Figure 120-3 Example of a non-registered application function to handle errors

120.2.3.2 Registering an error handler that does not use exceptions

The example code of Figure 120-4 and Figure 120-5 illustrates handling errors with a registered error handler that does not use exceptions.

A sequence of PK function calls is shown in Figure 120-4. After each call, the application checks the return status of the function before the next call is made. If an error is encountered somewhere, the registered error handler is invoked automatically just before the end of the failing PK function, and subsequently returns to that function.

 

	// call sequence of (related) PK functions
	PK_ERROR_t error = PK_XXX_fun_1( arg1, ..., argn );
	// check the error return code each time before continuing
	if (error == PK_ERROR_no_errors)
		error = PK_XXX_fun_2( arg1, ..., argm );
	if (error == PK_ERROR_no_errors)
		error = PK_XXX_fun_3( arg1, ..., argr );
	...
	
	// call error-processing PK functions outside of the error handler
	if (error != PK_ERROR_no_errors)
	{
		PK_LOGICAL_t was_error;
		PK_ERROR_sf_t error_sf;
		// get details of the error
		PK_THREAD_ask_last_error( &was_error, &error_sf );
		// process serious or fatal errors
		if (error_sf.severity == PK_ERROR_serious)
		{
	// roll back the current partition (and any other affected partitions)
			PK_SESSION_ask_curr_partition( &partition );
			PK_PARTITION_ask_pmark( partition, &pmark1, ... );
			PK_PMARK_goto_2
( pmark1, &n_new, &new_entities, ...);
			// free memory where necessary
			if (n_new) PK_MEMORY_free( new_entities );
		}
		else if (error_sf.severity == PK_ERROR_fatal)
		{
			// stop the current session
			PK_SESSION_stop();
	// call application function containing PK calls to start a new session
//and re-register the frustrum and delta frustrum
			restartParasolid();
		}
	}

Figure 120-4 Sequence of PK calls with a registered error handler that does not use exceptions (the code for the error handler is not shown in this figure)

The example error handler illustrated in Figure 120-5 provides information and performs application-specific clean-up tasks, but does not call any PK functions: the PK calls are made after returning to the application (as shown in Figure 120-4), in order to avoid leaving the Parasolid kernel in an inconsistent state. The actual flow of execution resembles that of the previous case (with no registered error handler).

 

PK_ERROR_code_t myApp::handlePKError( PK_ERROR_sf_t* error_sf )
{
	// set error information for the application
	myApp->setErrorStatus( true );
	myApp->setError( “PK”, error_sf.severity, ... );
	// report severity of error and failing function
	if (error_sf->severity == PK_ERROR_mild)
	{
		// warn user of a mild error
		Message( "Mild error in Parasolid function %s", error_sf->function );
		... // perform any further application-specific clean-up tasks
	}
	else if (error_sf->severity == PK_ERROR_serious)
	{
		// warn user of a serious error: for safety, do not call the PK here
		Message( "Serious error in Parasolid function %s", error_sf->function );
		... // perform any further application-specific clean-up tasks
	}
	else if (error_sf->severity == PK_ERROR_fatal)
	{
		// warn user of a fatal error: for safety, do not call the PK here
		Message( "Fatal error in Parasolid function %s", error_sf->function );
		... // perform any further application-specific clean-up tasks
	}
}

Figure 120-5 Example of a registered application function to handle errors without using exceptions

120.2.3.3 Registering an error handler that uses exceptions

The example code of Figure 120-6 and Figure 120-7 illustrates handling errors using a registered error handler that uses exceptions.

 

	try
	{
		// call sequence of (related) PK functions
		PK_XXX_fun_1( arg1, ..., argn );
		// no need to check the error return code each time
		PK_XXX_fun_2( arg1, ..., argm );
		PK_XXX_fun_3( arg1, ..., argr );
		...
	}
	
	...
	// could combine this with the catch statements in Figure 120-1
	catch(PK_ERROR_sf_t* error_sf)
	{
		if (error_sf->severity == PK_ERROR_mild)
		{
			// warn user of a mild error
			Message( "Mild error in Parasolid function %s", error_sf->function );
			... // perform any further application-specific clean-up tasks
		}
		else if (error_sf->severity == PK_ERROR_serious)
		{
			// warn user of a serious error
			Message( "Serious error in Parasolid function %s", error_sf->function );
	// roll back the current partition (and any other affected partitions)
			PK_SESSION_ask_curr_partition( &partition );
			PK_PARTITION_ask_pmark( partition, &pmark1, ... );
			PK_PMARK_goto_2
( pmark1, &n_new, &new_entities, ...);
			// free memory where necessary
			if (n_new) PK_MEMORY_free( new_entities );
			... // perform any further application-specific clean-up tasks
		}
		else if (error_sf->severity == PK_ERROR_fatal)
		{
			// warn user of a fatal error
			Message( "Fatal error in Parasolid function %s", error_sf->function );
			// stop the current session
			PK_SESSION_stop();
	// call application function containing PK calls to start a new session
//and re-register the frustrum and delta frustrum
			restartParasolid();
			... // perform any further application-specific clean-up tasks
		}
	}

Figure 120-6 Sequence of PK calls with a registered error handler using exceptions

A sequence of PK function calls takes place within a try block, as shown in Figure 120-6. There is no need for the application to check the return status each time, however, because in the event of an error, execution does not resume at the next call in the sequence. Instead, the error handler is automatically invoked. After first preparing the Parasolid kernel with a call to PK_THREAD_tidy, the error handler throws an exception that is caught by the catch statement shown in Figure 120-6.

In a real application, the error handler might throw different exceptions according to the severity of the error and other circumstances. The catch statements for these could be combined with those in Figure 120-1.

 

PK_ERROR_code_t myApp::handlePKError( PK_ERROR_sf_t* error_sf )
{
	// set the error information for the application
	setErrorStatus( true );
	setError( “PK”, error_sf->severity, ... );
	// tidy the Parasolid session before throwing an exception
	if (PK_THREAD_tidy() != PK_ERROR_no_errors)
		setPKTidyStatus( false );
	// throw an exception
	throw error_sf;
}

Figure 120-7 Example of a registered application function to handle errors using exceptions

 

Note: When your registered error handler throws an exception (and therefore passes control back to your application instead of Parasolid), you must call PK_THREAD_tidy before calling another PK function. This tidies the Parasolid kernel and internal memory; it must be done before the exception is thrown.

120.2.3.4 Benefits of registering an error handler

Registering an error handler allows Parasolid to report errors immediately, and perform any application-specific processing automatically. Better still, using an error handler that throws exceptions allows you to process PK errors fully automatically; your application no longer needs to check the return values of the PK calls.

120.2.4 Special errors

This section describes some unusual Parasolid errors that require special treatment, or arise under particular circumstances.

 

Error

Reason

Required action

PK_ERROR_system_error

Parasolid has failed in an unexpected way.

This error can arise when argument checking has been turned off and incorrect data are passed to a PK function.

Your application should proceed according to the severity reported.

PK_ERROR_fatal_error

A fatal error has occurred; the Parasolid session has been so badly corrupted that you cannot make any further PK calls.

This error can arise when run-time errors are processed by a signal handler; for details, see Chapter 121, “Signal Handling”.

Your application must stop and restart the Parasolid session in order to make further PK calls.

PK_ERROR_unhandleable_condition

An unforeseeable error has occurred that Parasolid cannot diagnose and process internally; hence no specific information can be given in the PK_ERROR_sf_t structure (see Section 120.2.5, “PK_ERROR functions and their use” for details).

This error can arise when run-time errors or user interrupts are processed by a signal handler. See Section 121, “Signal Handling” for details

If your application uses a registered error handler with exceptions, it must throw an exception back to the application code. If the error can be dealt with, it should be possible to continue the Parasolid session afterwards (having called PK_SESSION_tidy).

If your application does not use a registered error handler with exceptions, Parasolid will flush the output buffers, close open files and call exit() to terminate the current process.

PK_ERROR_run_time_error

A run-time error in the Parasolid kernel is being processed by a signal handler; for details, see Chapter 121, “Signal Handling”.

Your application should proceed according to the severity reported.

PK_ERROR_aborted

PK_SESSION_abort has been called by a signal handler as a result of a user interrupt; for details, see Chapter 121, “Signal Handling”.

Your application should proceed according to the severity reported.

PK_ERROR_cant_be_aborted

A user interrupt has been attempted during execution of a PK function that cannot be safely aborted; for details, see Chapter 121, “Signal Handling”.

No specific recovery action is required in your application.

Therefore a further advantage of using a registered error handler with exceptions is that Parasolid can recover from the error code PK_ERROR_unhandleable_condition. See Chapter 121, “Signal Handling” for further details

 

Note: If you encounter a system error and argument checking was not enabled, you should first enable it with a call to PK_SESSION_set_check_arguments and try the operation again before investigating further.

 

Note: Parasolid can detect string buffer overruns and other errors in its string formatting code, and reports these as PK_ERROR_run_time_error although no signal is raised. They should be handled in your application in the same way as other run-time errors.

120.2.5 PK_ERROR functions and their use

The error manipulation and enquiry functions available in Parasolid are described in the table below. They are used in situations where it is necessary to override the current error handler: for example, you might be developing a third-party plug-in for an existing Parasolid application, and have no knowledge of the master application’s error-handling strategy.

 

Note: When using multiple thread applications, it is recommended that you use PK_THREAD_ functions instead of PK_ERROR_ functions. See Section 113.2, “How to set up and use application threads” for a list of these functions.

 

Function

Description

PK_ERROR_ask_last

This function returns information about the last PK error raised. The information is returned (via the arguments) in a PK_ERROR_sf_t structure that includes:

  • The name of the PK function that raised the error
  • The error code
  • The severity of the error
  • The numbers and names of any invalid arguments
  • The entity to which the error applies

If there is no error, or an error has been cleared ( was_error is PK_LOGICAL_false), then this structure has the values indicated below:

PK_ERROR_clear_last

This function clears the information about the last PK error raised.

Subsequent calls to PK_ERROR_ask_last will not return any information until another error is raised.

PK_ERROR_raise

This function raises an (artificial) PK error, given as input in a PK_ERROR_sf_t structure.

If your application has registered an error handler, it is invoked, and appropriate action taken according to the severity of the new error. If the error handler uses exceptions, then this function may not return; otherwise, it returns the error code corresponding to the new error.

PK_ERROR_reraise

This function works in exactly the same way as PK_ERROR_raise, only it raises the last error that occurred (i.e., that which would be returned by PK_ERROR_ask_last).

The logical argument was_error is set to true unless there has not been an error or the error was previously cleared, in which case no error is raised.

PK_ERROR_register_callbacks

This function registers the error handler given as input in a PK_ERROR_frustrum_t structure. Your error handler must return a PK_ERROR_code_t and receive a pointer to a PK_ERROR_sf_t structure.

A different error handler can be registered at any time simply by calling this function with an appropriate pointer.

PK_ERROR_ask_callbacks

This function returns the current error handler as a pointer to a PK_ERROR_frustrum_t structure, if there is one. If not, it returns NULL.

The example third-party function in Figure 120-8 illustrates how the PK_ERROR_xxx functions and PK_THREAD_ xxx functions can be used. This function makes several calls to PK functions, and is designed not to be disrupted by mild errors. The behaviour of the master application’s error handler is not known, so it first replaces the current error handler (if any) with its own by calling PK_THREAD_register_error_cbs. The new error handler throws an exception for serious and fatal errors but not mild errors, as shown in Figure 120-9.

 

PK_ERROR_code_t thirdPartyApp::functionThatMakesPKCalls( void )
{
	PK_ERROR_frustrum_t master_app_frustrum;
	PK_LOGICAL_t was_error;
	// main body of function wrapped in a ‘try’ block
	try
	{
		PK_ERROR_frustrum_t tp_app_frustrum;
		// save the frustrum from the master application
		PK_THREAD_ask_error_cbs( &master_app_frustrum );
	// temporarily replace the current error handler 
//with ‘thirdPartyApp’ member function ‘handleError_NoMild’
		tp_app_frustrum.handler_fn = &handleError_NoMild;
		PK_THREAD_register_error_cbs( tp_app_frustrum );
		
		// clear the last error raised
		PK_THREAD_clear_last_error( &was_error );
		
		// call PK functions
		PK_XXX_fun_1( arg1, ..., argn );
		// no need to check the error return code each time
		PK_XXX_fun_2( arg1, ..., argm );
		PK_XXX_fun_3( arg1, ..., argr );
		...
		// re-register the frustrum from the master application
		PK_THREAD_register_error_cbs( master_app_frustrum );
		// check to see if a mild error occurred somewhere
		PK_ERROR_sf_t error_sf;
		PK_THREAD_ask_last_error( &was_error, &error_sf );
		// alert the master application if an error occurred
		if (was_error)
		{
	// if here, the error is mild, 
//so there is no need to re-raise it
			return error_sf.code;
		}
	}
	...
	// catch all exceptions (serious and fatal errors) here
	catch(...)
	{
		// re-register the frustrum from the master application
		PK_THREAD_register_error_cbs( master_app_frustrum );
	// re-raise the error with the original error handler; 
// if it returns (or does not exist), return the error code
		return PK_ERROR_reraise( &was_error );
	}
	// if here, no errors took place
	return PK_ERROR_no_errors;
}

Figure 120-8 Example of a third-party function that makes Parasolid calls

The third-party function clears the memory of the last error raised using PK_THREAD_clear_last_error, and then makes a series of calls to PK functions. If a serious or fatal error is encountered, the error handler throws an exception, and execution continues inside the catch(...) block in the function. Otherwise, execution continues in the try block; in each case, the master application’s error handler is re-registered.

If a mild error has occurred (as indicated by PK_THREAD_ask_last_error), the function returns the corresponding error code to the master application (for information), but does not raise an error. After a serious or fatal error, however, the function calls PK_ERROR_reraise to handle the error with the master application’s error handler (if one exists); if the error handler returns (or does not exist), the function returns the corresponding error code to the master application.

 

PK_ERROR_code_t thirdPartyApp::handleError_NoMild( PK_ERROR_sf_t* error_sf )
{
	// respond to serious and fatal errors only
	if (error_sf->severity != PK_ERROR_mild)
	{
		// tidy the session before throwing the exception
		PK_THREAD_tidy()
		throw error_sf->severity;
	}
}

Figure 120-9 Example of a third-party error handler that ignores mild errors

 

Warning: If you register an error handler with Parasolid, you must not call any of the PK_ERROR functions or PK_THREAD_equivalent functions described in this section from within the error handler.

[back to top]


120.3 Failure status codes

Some PK functions have the ability to return detailed diagnostic information following any failure to complete an operation in the manner intended. In these situations, it is not possible to return this information through the general PK_ERROR_sf structure; PK functions therefore return an error code of PK_ERROR_no_errors, and send error diagnostics back via a particular variable or structure among their output arguments known as a status code.

The documentation for each PK function indicates whether it may return failure information via a status code; if so, it tells you which variable to examine in order to determine the status (i.e., success or failure) of the operation.

120.3.1 Types of failure status code returned

Types of status code that are commonly used to indicate failures include:

(Please note that this is not a complete list.) This status code may appear explicitly among the output arguments of the function, or as a field within a larger data structure describing the results of the operation.

 

Warning: For functions that may return failure information via a status code (with an error code of PK_ERROR_no_errors), you must explicitly check the contents of their arguments in your application to establish the status of the operation. A registered error handler will not be called in these situations.

120.3.2 Necessary action following a failure status code

In many cases when a function returns a failure status code, the model has not been changed, and hence no Parasolid-specific action is required; this is analogous to situations in which PK functions return a mild error. In the case of local operations, however, it is possible that the model has been corrupted, and hence deleting it afterwards could lead to a run-time error. Specifically, the functions that may have corrupted the model after a failure are those that return a PK_local_status_t code.

 

Warning: If a function returns a failure status code of type PK_local_status_t, we recommend that you roll back to a valid state of the model, in order to avoid any possibility of a run-time error later.

In addition, for boolean operations, the return of the failure status code PK_boolean_result_failed_c may indicate that extra entities have been produced, causing undesirable changes to the model. The data structures should not be corrupt, but a call to PK_BODY_check or PK_FACE_check may show the model to be invalid. Therefore we also recommend that if PK_boolean_result_failed_c is returned from a call to PK_BODY_boolean_2 or PK_FACE_boolean_2, the application should roll back to a valid state of the model.

If you are dealing with multiple threads in your application and a failure status code is returned, you should roll the session back. See Section 113.6.1, “Excluding application threads after a serious or fatal error”.

[back to top]

<<< Introduction To Error Handling Chapters Signal Handling >>>