mirror of
https://github.com/corda/corda.git
synced 2025-06-22 17:09:00 +00:00
[EG-440] Add some error codes and the error resource generation tool (#6192)
* [EG-438] First commit of error code interface * [EG-438] Implement error reporter and a few error codes * [EG-438] Add unit tests and default properties files * [EG-438] Add the error table builder * [EG-438] Update initial properties files * [EG-438] Add some Irish tests and the build.gradle * [EG-438] Fall back for aliases and use different resource strategy * [EG-438] Define the URL using a project-specific context * [EG-438] Tidy up initialization code * [EG-438] Add testing to generator and tidy up * [EG-438] Remove direct dependency on core and add own logging config * [EG-438] Fix compiler warnings and tidy up logging * [EG-438] Fix detekt warnings * [EG-438] Improve error messages * [EG-438] Address first set of review comments * [EG-438] Use enums and a builder for the reporter * [EG-438] Address first set of review comments * [EG-438] Use enums and a builder for the reporter * [EG-438] Add kdocs for error resource static methods * [EG-440] Add error code for duplicate CorDapp loading * [EG-438] Handle enums defined with underscores * [EG-440] Add errors for some CorDapp loading scenarios * [EG-440] Finish adding errors for CorDapp loading * [EG-440] Fix up errors in properties files * [EG-440] Start change to error code definition * [EG-440] Update error code definition and add resource generation tool * [EG-440] Tidy up error resource generation tool frontend * [EG-440] Small refactorings and add kdocs * [EG-440] Generate all missing resources * [EG-440] Some refactoring and start writing a test * [EG-440] Update unit test for resource generator * [EG-440] Renaming of various parts of the error tool * [EG-440] Add testing for errors and fix an issue in resource generation * [EG-440] Add a kdoc for context provider API * [EG-440] Remove old code from repository * [EG-440] Address some review comments
This commit is contained in:
@ -43,6 +43,11 @@ class ErrorReporting private constructor(private val localeString: String,
|
||||
return ErrorReporting(localeString, location, contextProvider)
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the context provider to supply project-specific information about the errors.
|
||||
*
|
||||
* @param contextProvider The context provider to use with error reporting
|
||||
*/
|
||||
fun withContextProvider(contextProvider: ErrorContextProvider) : ErrorReporting {
|
||||
return ErrorReporting(localeString, resourceLocation, contextProvider)
|
||||
}
|
||||
|
@ -4,7 +4,8 @@ package net.corda.common.logging.errorReporting
|
||||
* Namespaces for errors within the node.
|
||||
*/
|
||||
enum class NodeNamespaces {
|
||||
DATABASE
|
||||
DATABASE,
|
||||
CORDAPP
|
||||
}
|
||||
|
||||
/**
|
||||
@ -17,4 +18,16 @@ enum class NodeDatabaseErrors : ErrorCodes {
|
||||
PASSWORD_REQUIRED_FOR_H2;
|
||||
|
||||
override val namespace = NodeNamespaces.DATABASE.toString()
|
||||
}
|
||||
|
||||
/**
|
||||
* Errors related to loading of Cordapps
|
||||
*/
|
||||
enum class CordappErrors : ErrorCodes {
|
||||
DUPLICATE_CORDAPPS_INSTALLED,
|
||||
MULTIPLE_CORDAPPS_FOR_FLOW,
|
||||
MISSING_VERSION_ATTRIBUTE,
|
||||
INVALID_VERSION_IDENTIFIER;
|
||||
|
||||
override val namespace = NodeNamespaces.CORDAPP.toString()
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
errorTemplate = The CorDapp (name: {0}, file: {1}) is installed multiple times on the node. The following files correspond to the exact same content: {2}
|
||||
shortDescription = A CorDapp has been installed multiple times on the same node.
|
||||
actionsToFix = Investigate the logs to determine the files with duplicate content, and remove one of them from the cordapps directory.
|
||||
aliases = iw8d4e
|
@ -0,0 +1,3 @@
|
||||
errorTemplate = The CorDapp (name: {0}, file: {1}) is installed multiple times on the node. The following files correspond to the exact same content: {2}
|
||||
shortDescription = A CorDapp has been installed multiple times on the same node.
|
||||
actionsToFix = Investigate the logs to determine the files with duplicate content, and remove one of them from the cordapps directory.
|
@ -0,0 +1,4 @@
|
||||
errorTemplate = Version identifier ({0}) for attribute {1} must be a whole number starting from 1.
|
||||
shortDescription = A version attribute was specified in the CorDapp manifest with an invalid value. The value must be a whole number, and it must be greater than or equal to 1.
|
||||
actionsToFix = Investigate the logs to find the invalid attribute, and change the attribute value to be valid (a whole number greater than or equal to 1).
|
||||
aliases =
|
@ -0,0 +1,4 @@
|
||||
errorTemplate = Version identifier ({0}) for attribute {1} must be a whole number starting from 1.
|
||||
shortDescription = A version attribute was specified in the CorDapp manifest with an invalid value. The value must be a whole number, and it must be greater than or equal to 1.
|
||||
actionsToFix = Investigate the logs to find the invalid attribute, and change the attribute value to be valid (a whole number greater than or equal to 1).
|
||||
aliases =
|
@ -0,0 +1,4 @@
|
||||
errorTemplate = Target versionId attribute {0} not specified. Please specify a whole number starting from 1.
|
||||
shortDescription = A required version attribute was not specified in the manifest of the CorDapp JAR.
|
||||
actionsToFix = Investigate the logs to find out which version attribute has not been specified, and add that version attribute to the CorDapp manifest.
|
||||
aliases =
|
@ -0,0 +1,3 @@
|
||||
errorTemplate = Target versionId attribute {0} not specified. Please specify a whole number starting from 1.
|
||||
shortDescription = A required version attribute was not specified in the manifest of the CorDapp JAR.
|
||||
actionsToFix = Investigate the logs to find out which version attribute has not been specified, and add that version attribute to the CorDapp manifest.
|
@ -0,0 +1,4 @@
|
||||
errorTemplate = There are multiple CorDapp JARs on the classpath for the flow {0}: [{1}]
|
||||
shortDescription = Multiple CorDapp JARs on the classpath define the same flow class. As a result, the platform will not know which version of the flow to start when the flow is invoked.
|
||||
actionsToFix = Investigate the logs to find out which CorDapp JARs define the same flow classes. The developers of these apps will need to resolve the clash.
|
||||
aliases =
|
@ -0,0 +1,4 @@
|
||||
errorTemplate = There are multiple CorDapp JARs on the classpath for the flow {0}: [{1}]
|
||||
shortDescription = Multiple CorDapp JARs on the classpath define the same flow class. As a result, the platform will not know which version of the flow to start when the flow is invoked.
|
||||
actionsToFix = Investigate the logs to find out which CorDapp JARs define the same flow classes. The developers of these apps will need to resolve the clash.
|
||||
aliases =
|
@ -0,0 +1,12 @@
|
||||
package net.corda.commmon.logging.errorReporting
|
||||
|
||||
import net.corda.common.logging.errorReporting.CordappErrors
|
||||
|
||||
class CordappErrorsTest : ErrorCodeTest<CordappErrors>(CordappErrors::class.java, true) {
|
||||
override val dataForCodes = mapOf(
|
||||
CordappErrors.MISSING_VERSION_ATTRIBUTE to listOf("test-attribute"),
|
||||
CordappErrors.INVALID_VERSION_IDENTIFIER to listOf(-1, "test-attribute"),
|
||||
CordappErrors.MULTIPLE_CORDAPPS_FOR_FLOW to listOf("MyTestFlow", "Jar 1, Jar 2"),
|
||||
CordappErrors.DUPLICATE_CORDAPPS_INSTALLED to listOf("TestCordapp", "testapp.jar", "testapp2.jar")
|
||||
)
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package net.corda.commmon.logging.errorReporting
|
||||
|
||||
import net.corda.common.logging.errorReporting.NodeDatabaseErrors
|
||||
import java.net.InetAddress
|
||||
|
||||
class DatabaseErrorsTest : ErrorCodeTest<NodeDatabaseErrors>(NodeDatabaseErrors::class.java) {
|
||||
override val dataForCodes = mapOf(
|
||||
NodeDatabaseErrors.COULD_NOT_CONNECT to listOf<Any>(),
|
||||
NodeDatabaseErrors.FAILED_STARTUP to listOf(),
|
||||
NodeDatabaseErrors.MISSING_DRIVER to listOf(),
|
||||
NodeDatabaseErrors.PASSWORD_REQUIRED_FOR_H2 to listOf(InetAddress.getLocalHost())
|
||||
)
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
package net.corda.commmon.logging.errorReporting
|
||||
|
||||
import junit.framework.TestCase.assertFalse
|
||||
import net.corda.common.logging.errorReporting.ErrorCode
|
||||
import net.corda.common.logging.errorReporting.ErrorCodes
|
||||
import net.corda.common.logging.errorReporting.ErrorResource
|
||||
import net.corda.common.logging.errorReporting.ResourceBundleProperties
|
||||
import org.junit.Test
|
||||
import java.util.*
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
/**
|
||||
* Utility for testing that error code resource files behave as expected.
|
||||
*
|
||||
* This allows for testing that error messages are printed correctly if they are provided the correct parameters. The test will fail if any
|
||||
* of the parameters of the template are not filled in.
|
||||
*
|
||||
* To use, override the `dataForCodes` with a map from an error code enum value to a list of parameters the message template takes. If any
|
||||
* are missed, the test will fail.
|
||||
*
|
||||
* `printProperties`, if set to true, will print the properties out the resource files, with the error message filled in. This allows the
|
||||
* message to be inspected.
|
||||
*/
|
||||
abstract class ErrorCodeTest<T>(private val clazz: Class<T>,
|
||||
private val printProperties: Boolean = false) where T: Enum<T>, T: ErrorCodes {
|
||||
|
||||
abstract val dataForCodes: Map<T, List<Any>>
|
||||
|
||||
private class TestError<T>(override val code: T,
|
||||
override val parameters: List<Any>) : ErrorCode<T> where T: Enum<T>, T: ErrorCodes
|
||||
|
||||
@Test(timeout = 300_000)
|
||||
fun `test error codes`() {
|
||||
for ((code, params) in dataForCodes) {
|
||||
val error = TestError(code, params)
|
||||
val resource = ErrorResource.fromErrorCode(error, "error-codes", Locale.forLanguageTag("en-US"))
|
||||
val message = resource.getErrorMessage(error.parameters.toTypedArray())
|
||||
assertFalse(
|
||||
"The error message reported for code $code contains missing parameters",
|
||||
message.contains("\\{.*}".toRegex())
|
||||
)
|
||||
val otherProperties = Triple(resource.shortDescription, resource.actionsToFix, resource.aliases)
|
||||
if (printProperties) {
|
||||
println("Data for $code")
|
||||
println("Error Message = $message")
|
||||
println("${ResourceBundleProperties.SHORT_DESCRIPTION} = ${otherProperties.first}")
|
||||
println("${ResourceBundleProperties.ACTIONS_TO_FIX} = ${otherProperties.second}")
|
||||
println("${ResourceBundleProperties.ALIASES} = ${otherProperties.third}")
|
||||
println("")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test(timeout = 300_000)
|
||||
fun `ensure all error codes tested`() {
|
||||
val expected = clazz.enumConstants.toSet()
|
||||
val actual = dataForCodes.keys.toSet()
|
||||
val missing = expected - actual
|
||||
assertTrue(missing.isEmpty(), "The following codes have not been tested: $missing")
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user