Troubleshooting
Non-blocking exception handling
The default behavior for ODF 2 is to record all unhandled exceptions to a special table in Data Stores and to change the status of the corresponding transaction to reflect that. Therefore, if a transaction makes it to the end of a Business Process (BP), this does not mean the transaction is successful—you have to check its status.
To disable the default behavior, the usecase.properties file, add the errorHandlingEnabled=false line. In this case, any unhandled exception is immediately wrapped into OdfDeveloperException and re-thrown. For BP execution, the behavior is the same as in old pre-ODF2 projects: any exception stops executing the entire record in BP.
Errors when running Business Process in Control Tower
important
For exceptions in a Business Process, it is important to distinguish between the ones you can handle as ODF 2 exceptions and the ones causing exceptions outside of ODF 2.
Error in Event log for BP run
Usually, exceptions in ODF2 do not entail any records made to the error log. If an error appears in the Control Tower (CT) error log, it means either of the two things:
The default exception handling behavior is disabled. In this case, act as you usually do to handle stack traces.
Something happened outside of the ODF2 code. Analyze the stack trace in the CT error log. Review the RPA Worker log. Most likely, it is an infrastructure-related issue.
To access the Control Tower and RPA Worker logs via IA Cloud Developer, use the Launcher application. For access to logs via IA Cloud Enterprise, use Platform Monitor as described in the following guides:
Warning in Event log for BP run
When ODF2 catches an otherwise unhandled exception, and the default error handling mechanism is not disabled, the latter logs a warning that states the following: "Error was raised inside ODF task”. Check the ds_uc_<uc_name>_exception_v
If the exception is wrapped in
OdfException, it means that something happened within the framework code. For example, the configuration is incorrect, or there’s a database issue, and so on.If the exception is wrapped in
BusinessException, it means that it was explicitly raised in the Bot Task code.
In any case, act the same way as you usually do to handle stack traces.
Encountered issues
Project creation issues
If creating a project from an Archetype fails, make sure the Use Case name and code are specified because these are required parameters. For more information, refer to the Start Maven project article.
Database issues
Incorrect table structure
Errors due to the incorrect table structure (for instance, expected columns missing) are often associated with Liquibase migrations. Either a change in an entity class was not reflected in migrations, or migrations were not appropriately applied to the database. For details, refer to Data Model Management | Use Liquibase migrations.
BP errors related to the database structure are recorded in the Event log as: Error was raised inside ODF task. To check the error cause, search the Worker log for the exception stack trace with detailed information.
Incorrect table name
Cases, when ODF2 expects a table to be named not like it is really named, are usually due to a misconfiguration. The structure of the Data Store table name that ODF2 expects to find is as follows:
ds_uc_<usecase-code>_<table-name>_v<version>
The Use Case code is defined in the usecase.properties file. For projects created from an Archetype, it is mainly specified in the <properties> section of pom.xml and is added to the above file via templating in Maven.
To resolve the table name-related issues, explore the following possible root causes:
If a part of a table name differs from what ODF2 expects, it can mean the Use Case code was changed, but migrations were not updated accordingly.
If ODF2 attempts to find a table named like
ds_uc_<table-name>_v<version>, the behavior implies the Use Case code is missing from theusecase.propertiesfile. This can also mean that there is nousecase.propertiesfile in the classpath of the BCB (Bot Config Bundle) containing the Task class from which the associated Bot Task was generated. If it is a new module in a project, make sure you added it in accordance with the Add BCB module article.A table name is derived from the name of an entity class. If the table name differs from the one stored in the database, it can mean that the associated entity class was renamed, which was not reflected in migrations, or migrations were not applied to the database properly. For details, refer to Data Model Management | Use Liquibase migrations.
Similar to the Use Case code, the Use Case version is defined in the usecase.properties file. Therefore, for resolving issues related to the Use Case version misconfigurations, use the same approach.
Deadlocks on tables with large amount of data
Entities extended from the com.workfusion.odf2.core.orm.OdfEntity class have a field with the type UUID as a unique identifier. This field is also used as a search key to find a particular object.
In OrmLite, the fields with the type UUID are mapped to columns with the varchar data type (varchar(36) in the case of ODF 2 fields). Due to the bug in the MSSQL jdbs driver, varchar(36) in a Java prepared statement is transformed to varchar(4000) in an MSSQL request on the server.
For tables with a large amount of data (more than 100 thousand records), such transformation, along with using other varchar fields as search keys, dramatically decreases the performance of select requests and can cause a deadlock on updates.
To avoid deadlocks, you can use the raw query functionality of OrmLite. Instead of calling an update using a repository class, use constructions like the one below:
com.j256.ormlite.dao.Dao.updateRaw(”update entity set some_file=? where ds_uc_entity_v1='uuid_value', newValue)
Asset Bundle import issues
See Asset Bundle troubleshooting for the troubleshooting guide.
Versioning issues
When building a project, if you increase its version without due account to the ODF2 project structure, some assets in the project may have their versions unchanged, which can result in a number of problems during deployment. Make sure your asset naming conventions are in accordance with the versioning plugin documentation, and you are following the versioning flow described in it. In the documentation, you can also find potential problems and possible solutions.
Issues related to Bot Task jUnit tests
The most common failures of Bot Task tests are due to no mock infrastructure created as required by the task code.
In this case, the first suspect is database tables. The Bot Task testing engine cannot create any tables by default—you have to create even the transaction table explicitly before running a task. If a required table is missing, you will know it by the error message of similar content: org.h2.jdbc.JdbcSQLSyntaxErrorException: Table "ds_uc_odf2_it_transaction_v1_0" not found.
Typically, tables for Transaction, ErrorEntity, MonitorEntity, and MonitorConfigurationEntity are required. To mock those, inject com.workfusion.odf2.junit.OrmSupport and use its API as described in the Bot Task JUnit documentation.
Other standard services a tested task can require and you can mock are S3, OCR, and Secrets Vault. So, if an error message or a stack trace contains references to the services, make sure they are properly mocked in your test.
Issues related to Spoke tests
HTTP 401
When running the Control Tower environment for the first time with SSO enabled, you can fail to authenticate under an existing valid user if there is a known CT-to-Keycloak synchronization issue. After the first login to the CT web interface, the issue is resolved naturally—without any special troubleshooting efforts.
The second known issue is related to the Spoke design in terms of executing HTTP requests. If authentication fails for some reason (for instance, a user has entered a wrong password by mistake) during a test, Spoke does not stop the execution immediately. Instead, it calls a REST method—usually, /bundle-import—without a valid token from the server. At this point, the server responds with the 403 error—meaning the incoming request includes no authentication token. After that, if the retry mechanism is enabled, Spoke performs the same operations, including authentication, repeatedly with the same result. After five failed attempts, Keycloak locks the user temporarily, and all subsequent requests fail, even with valid credentials.
So, when a user specifies wrong credentials, Spoke won't let you know that. Instead, it sends multiple authentication requests, blocking the user completely. After that, the only way to recover is to wait until the user is unlocked automatically or goes to the Keycloak UI to unlock manually.
HTTP 403
Such an error shows that the user, under which Spoke connects to Control Tower, lacks the permissions required to upload an Asset Bundle.
Timeout exceeded
When importing an Asset Bundle to Control Tower via Spoke, you can get the following message: “Upload failed: wait time elapsed.” It means that the bundle upload is taking more time than the Asset Bundle import API is configured to wait. When you call controlTower.importAssetBundle(myBundle), the API uses the default five-minute timeout. There is an option to pass a custom import timeout by calling controlTower.importAssetBundle(myBundle, Await.atMost(myDuration)).
If such an error appears suddenly, it can mean the load of the Control Tower instance is unusually heavy, or network conditions are degraded abruptly.
The same reasons can cause a test to fail on a subsequent stage as you wait for a BP execution to finish. In this case, the timeout is configured in the .run().waitFor(myDuration) clause.
important
By inherent design, some Business Processes cannot be completed without manual interactions or depend on external services with complex or unpredictable behaviors, and therefore the BPs consistently cause exceeded timeouts when run. Such BPs are not suitable for running via Spoke without modifications.
To build integration tests for the BPs, mock the tasks causing the undesired behavior, which can also include Monitor steps. For more information on mocking Bot Tasks in Spoke, refer to the Business Process integration testing article.
Other Asset Bundle import problems
As Spoke uses the Asset Bundle import API, the issues described in the previous section apply to Spoke-based tests as well.