{"record":{"id":"ec75a193c442e3af","repo":"pentaho/pentaho-kettle","slug":"basemessages-getstring-packageclass-key-parameters-localized","errorCode":null,"errorMessage":"BaseMessages.getString( packageClass, key, parameters ) (localized message, dynamic)","messagePattern":"BaseMessages\\.getString\\( packageClass, key, parameters \\) \\(localized message, dynamic\\)","errorType":"exception","errorClass":"KettleDatabaseException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/pentaho/di/core/database/util/DatabaseLogExceptionFactory.java","lineNumber":121,"sourceCode":"  private static DatabaseInterfaceExtended extractDatabase( LogTableCoreInterface table ) {\n    DatabaseInterfaceExtended result = null;\n    if ( table != null && table.getDatabaseMeta() != null ) {\n      DatabaseInterface databaseInterface = table.getDatabaseMeta().getDatabaseInterface();\n      result =\n          databaseInterface instanceof DatabaseInterfaceExtended ? (DatabaseInterfaceExtended) databaseInterface : null;\n    }\n    return result;\n  }\n\n  /**\n   * Throw exception back to caller, this will be logged somewhere else.\n   */\n  private static class ThrowableBehaviour implements LogExceptionBehaviourInterface {\n\n    @Override\n    public void registerException( LogChannelInterface log, Class<?> packageClass, String key, String... parameters )\n        throws KettleDatabaseException {\n      throw new KettleDatabaseException( BaseMessages.getString( packageClass, key, parameters ) );\n    }\n\n    @Override public void registerException( LogChannelInterface log, Exception e, Class<?> packageClass, String key,\n        String... parameters ) throws KettleDatabaseException {\n      throw new KettleDatabaseException( BaseMessages.getString( packageClass, key, parameters ), e );\n    }\n  }\n\n  /**\n   * Suppress exception, but still add a log record about it\n   */\n  private static class SuppressBehaviour implements LogExceptionBehaviourInterface {\n\n    @Override\n    public void registerException( LogChannelInterface log, Class<?> packageClass, String key, String... parameters ) {\n      log.logError( BaseMessages.getString( packageClass, key, parameters ) );\n    }\n","sourceCodeStart":103,"sourceCodeEnd":139,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/core/src/main/java/org/pentaho/di/core/database/util/DatabaseLogExceptionFactory.java#L103-L139","documentation":"DatabaseLogExceptionFactory's ThrowableBehaviour registers a database log record and throws a KettleDatabaseException whose message is produced by BaseMessages.getString(packageClass, key, parameters) — a localized message looked up from a message bundle with optional {0}-style parameters. It is thrown so the caller sees a localized, formatted error while the same text is written to the log channel.","triggerScenarios":"Calling DatabaseLogExceptionFactory.registerException(log, packageClass, key, parameters...) (or the overload with a cause Exception) where the given key exists or is missing in the packageClass message bundle; any runtime failure in BaseMessages lookup formatting also surfaces here.","commonSituations":"Plugin code using the exception factory with a typo'd message key or wrong packageClass, or passing parameters that don't match the bundle placeholders, yielding 'Message not found in key' style output wrapped in a KettleDatabaseException.","solutions":["Fix the packageClass/key pair so it matches an entry in the bundle's messages.properties files.","Verify the parameter count matches the placeholders in the localized message.","Check the kettle locales directory contains the properties file for packageClass on the classpath.","Catch KettleDatabaseException at the call site and log the actual cause if the localized message is unhelpful."],"exampleFix":"// before\nDatabaseLogExceptionFactory.getExceptionBehaviour().registerException(log, PKG, \"MyPlugin.WrongKey.Error\");\n// after\nDatabaseLogExceptionFactory.getExceptionBehaviour().registerException(log, PKG, \"MyPlugin.ConnectionFailed.Error\", tableName);","handlingStrategy":"try-catch","validationCode":"// validate the key exists before calling\nString msg = BaseMessages.getString( PKG, \"MyPlugin.ConnectionFailed.Error\" );\nif ( msg.startsWith( \"!\" ) ) throw new IllegalStateException( \"Missing message key\" );","typeGuard":null,"tryCatchPattern":"try {\n  behaviour.registerException( log, PKG, KEY, params );\n} catch ( KettleDatabaseException e ) {\n  log.logError( \"DB operation failed\", e );\n  // inspect e.getMessage() and the message bundle\n}","preventionTips":["Keep message keys referenced from code in sync with messages.properties","Unit-test localized lookups for every key used with the exception factory","Match parameter count to bundle placeholders","Use constants for keys instead of inline strings"],"tags":["kettle","localization","database-exception"],"backgroundTag":"resource-not-found","analyzedSha":"f3058517a153da500bf4551f46d79b91bf8ec552","analyzedAt":"2026-09-13T14:04:16.340Z","contentChangedAt":"2026-09-13T14:04:16.340Z","schemaVersion":2},"datasetVersion":"2026-09-20T23:17:15.980Z"}