{"record":{"id":"3f4853e4f57e1ff2","repo":"baomidou/mybatis-plus","slug":"execute-fail","errorCode":null,"errorMessage":"Execute {} fail. ","messagePattern":"Execute (.+?) fail\\. ","errorType":"exception","errorClass":"SQLException","httpStatus":null,"severity":"error","filePath":"mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/ddl/DdlScriptErrorHandler.java","lineNumber":66,"sourceCode":"\n        public static final Log log = LogFactory.getLog(PrintlnLogErrorHandler.class);\n\n        @Override\n        public void handle(String sqlFile, Exception throwable) {\n            log.error(\"run script sql:\" + sqlFile + \", error: \", throwable);\n        }\n    }\n\n    /**\n     * 抛出错误 (中断后续文件执行)\n     */\n    class ThrowsErrorHandler implements DdlScriptErrorHandler {\n\n        public static final ThrowsErrorHandler INSTANCE = new ThrowsErrorHandler();\n\n        @Override\n        public void handle(String sqlFile, Exception throwable) throws SQLException {\n            throw new SQLException(\"Execute \" + sqlFile + \" fail. \", throwable);\n        }\n\n    }\n\n}\n\n\n","sourceCodeStart":48,"sourceCodeEnd":74,"githubUrl":"https://github.com/baomidou/mybatis-plus/blob/bf67d907478c724120bf76292da54abf9e73c2b3/mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/ddl/DdlScriptErrorHandler.java#L48-L74","documentation":"ThrowsErrorHandler is the default error handler for DdlHelper's script runner: when executing a SQL script file throws, it rethrows the cause wrapped in SQLException('Execute <sqlFile> fail. '). The message intentionally names the script file; the real reason (syntax error, missing table, constraint violation) is the nested throwable. Aborting is the point — this handler '中断后续文件执行' (stops subsequent files).","triggerScenarios":"DdlScriptRunner (or DdlHelper.runScript) executing .sql files where any statement fails: invalid SQL for the target dialect, missing privileges, object already exists (scripts not idempotent), or wrong delimiters/statement splitting for procedures. With the default throws-error-handler the first failure aborts the run.","commonSituations":"Running schema migrations at startup against a partially-initialized schema (tables already exist); scripts written for MySQL executed on PostgreSQL; missing DELIMITER handling for stored routines; CI runs without Flyway/Liquibase idempotency conventions.","solutions":["Read the nested exception (throwable cause) — it contains the driver's actual error and statement context.","Fix the offending script: make it idempotent (CREATE TABLE IF NOT EXISTS, DROP IF EXISTS) or correct the dialect-specific syntax.","If best-effort continuation is desired, configure the script runner with the ignore/log error handler instead of the default ThrowsErrorHandler.","Verify statement delimiters and script encoding match the runner's expectations."],"exampleFix":"-- before: fails on re-run -> SQLException('Execute schema.sql fail.')\nCREATE TABLE t_user (id BIGINT PRIMARY KEY, name VARCHAR(64));\n\n-- after: idempotent DDL (MySQL example)\nCREATE TABLE IF NOT EXISTS t_user (id BIGINT PRIMARY KEY, name VARCHAR(64));","handlingStrategy":"try-catch","validationCode":"if (!Files.exists(scriptPath) || Files.size(scriptPath) == 0) {\n    throw new IllegalStateException(\"missing or empty DDL script: \" + scriptPath);\n}","typeGuard":null,"tryCatchPattern":"try {\n    ddlScriptRunner.execute(sqlFile);\n} catch (SQLException e) {\n    Throwable cause = e.getCause(); // driver-level reason for the failing statement\n    throw new IllegalStateException(\"DDL script \" + sqlFile + \" failed: \" + cause, e);\n}","preventionTips":["Make DDL scripts idempotent (IF NOT EXISTS / DROP IF EXISTS).","Match script dialect to the target database and validate on a scratch schema in CI.","If continuation is acceptable, configure a logging error handler instead of the default ThrowsErrorHandler."],"tags":["ddl","sql-script","migration","database"],"backgroundTag":null,"analyzedSha":"bf67d907478c724120bf76292da54abf9e73c2b3","analyzedAt":"2026-08-14T15:17:09.543Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}