erikbra/grate

Improve error messages on SQL errors

Closed this issue · 0 comments

Describe the bug
When there are errors in one SQL script, it's very difficult to see where the error is. The Sql clients do report errors, but we don't handle them very well, just spit out a (rather meaningless) stack trace.

To Reproduce
Run grate with one or many scripts containing errors

Expected behavior

I get a nice error message, telling me:

  • Which file had the error (at least)
  • Where in the file the error was (if this is easy to get out of the exception thrown in the DB provider)

I don't get a stacktrace. I don't care about the internal structure/code of grate, as a user 😉

Screenshots

Output from run:

Unhandled exception: grate.Exceptions.MigrationFailed: Migration failed due to errors:
 * Ambiguous column name 'InsertTimestamp'.
 ---> Microsoft.Data.SqlClient.SqlException (0x80131904): Ambiguous column name 'InsertTimestamp'.
   at Microsoft.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at Microsoft.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at Microsoft.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
   at Microsoft.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
   at Microsoft.Data.SqlClient.SqlCommand.InternalEndExecuteNonQuery(IAsyncResult asyncResult, Boolean isInternal, String endMethod)
   at Microsoft.Data.SqlClient.SqlCommand.EndExecuteNonQueryInternal(IAsyncResult asyncResult)
   at Microsoft.Data.SqlClient.SqlCommand.EndExecuteNonQueryAsync(IAsyncResult asyncResult)
   at Microsoft.Data.SqlClient.SqlCommand.<>c.<InternalExecuteNonQueryAsync>b__210_1(IAsyncResult result)
   at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult, Func`2, Action`1, Task`1, Boolean)
--- End of stack trace from previous location ---
   at grate.Migration.AnsiSqlDatabase.ExecuteNonQuery(DbConnection conn, String sql, Nullable`1 timeout)
   at grate.Migration.AnsiSqlDatabase.ExecuteNonQuery(DbConnection conn, String sql, Nullable`1 timeout)
   at grate.Migration.AnsiSqlDatabase.RunSql(String sql, ConnectionType connectionType, TransactionHandling transactionHandling)
   at grate.Migration.DbMigrator.RunTheActualSql(String sql, String scriptName, MigrationType migrationType, Int64 versionId, ConnectionType connectionType, TransactionHandling transactionHandling)
   at grate.Migration.DbMigrator.RunTheActualSql(String sql, String scriptName, MigrationType migrationType, Int64 versionId, ConnectionType connectionType, TransactionHandling transactionHandling)
   at grate.Migration.DbMigrator.<>c__DisplayClass25_0.<<RunSql>g__LogAndRunSql|0>d.MoveNext()
--- End of stack trace from previous location ---
   at grate.Migration.DbMigrator.RunSql(String sql, String scriptName, MigrationType migrationType, Int64 versionId, GrateEnvironment environment, ConnectionType connectionType, TransactionHandling transactionHandling)
   at grate.Migration.GrateMigrator.Process(DirectoryInfo root, MigrationsFolder folder, String changeDropFolder, Int64 versionId, ConnectionType connectionType, TransactionHandling transactionHandling)
   at grate.Migration.GrateMigrator.LogAndProcess(DirectoryInfo root, MigrationsFolder folder, String changeDropFolder, Int64 versionId, ConnectionType connectionType, TransactionHandling transactionHandling)
   at grate.Migration.GrateMigrator.Migrate()
ClientConnectionId:bd3dbe26-62ef-4f98-801d-3deb65bb94cc
Error Number:209,State:1,Class:16

Screenshot:

image

Desktop (please complete the following information):

  • OS: All
  • Version: All

Additional context