Upgrading to V2
Exceptional V2 is a major and breaking release in an effort to simplify settings, unify the experience, and add a few missing features from V1. This means that your code likely breaks in a few places, and schemas for storage for SQL providers will need an update.
This doc describes how to upgrade each area of Exceptional you may be using:
Logging
Loging has shifted from static methods (Error.Log()
/Error.LogNoContext()
) to extension methods (.Log()
/.LogNoContext()
) on Exception
itself. Example usage in a controller:
catch (SqlException e)
{
e.Log(Context);
}
Note: .Log()
is defined separately for ASP.NET (in the StackExchange.Exceptional
library) and ASP.NET Core (in the StackExchange.Exceptional.AspNetCore
), due to the HttpContext
we extract data from being different.
Category is a new string field on Error
(and an optional parameter on .Log()
) for further subclassifying errors in an application. This could also be set in a handler for example.
Controller (ASP.NET non-Core)
A route that forwards to the exceptional module for handling now looks like this:
[Route("dev/errors/{resource?}/{subResource?}")]
public Task Exceptions() => ExceptionalModule.HandleRequestAsync(System.Web.HttpContext.Current);
Settings
Settings are now in .ExceptionalSettings
(defined in the StackExchange.Exceptional
and StackExchange.Exceptional.AspNetCore
libraries.
The StackExchange.Exceptional
(ASP.NET non-Core) package tries to ensure backwards compatability with existing Web.config
layouts with shims. If something doesn’t work, please file an issue!
The rest of the settings that were spread across Error
and ErrorStore
are now unified in ExceptionalSettings
. See the sample applications for configure-by-code examples in your respective platform. Settings are also avaialble statically if needed at ExceptionalConfig.Settings
, for example:
ExceptionalConfig.Settings.Store.ApplicationName = "MyApp";
SQL Server
- Run the same script use for initial setup, it’s now an upgrade script as well: SqlServer.sql
Note: If you are deploying many services that share a store, you can do this in 2 phases by separating out the scripts. Before your first deploy:
If Not Exists (Select 1 From INFORMATION_SCHEMA.COLUMNS Where TABLE_NAME = 'Exceptions' And COLUMN_NAME = 'LastLogDate')
Begin
Alter Table [dbo].[Exceptions] Add [LastLogDate] [datetime] Null;
End
If Not Exists (Select 1 From INFORMATION_SCHEMA.COLUMNS Where TABLE_NAME = 'Exceptions' And COLUMN_NAME = 'Category')
Begin
Alter Table [dbo].[Exceptions] Add [Category] nvarchar(100) Null;
End
To cleanup after the last V1 instance is removed:
If Exists (Select 1 From INFORMATION_SCHEMA.COLUMNS Where TABLE_NAME = 'Exceptions' And COLUMN_NAME = 'SQL')
Begin
Alter Table [dbo].[Exceptions] Drop Column [SQL];
End
MySQL
- Run the same script use for initial setup, it’s now an upgrade script as well: MySQL.sql
Note: If you are deploying many services that share a store, you can do this in 2 phases by separating out the scripts. Before your first deploy:
SELECT IF (EXISTS(SELECT 1
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'Exceptions'
AND COLUMN_NAME = 'LastLogDate')
,'Select ''Already There'''
,'ALTER TABLE `Exceptions` ADD LastLogDate datetime NULL;')
INTO @a;
PREPARE q1 FROM @a;
EXECUTE q1;
DEALLOCATE PREPARE q1;
SELECT IF (EXISTS(SELECT 1
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'Exceptions'
AND COLUMN_NAME = 'Category')
,'Select ''Already There'''
,'ALTER TABLE `Exceptions` ADD Category nvarchar(100) NULL;')
INTO @a;
PREPARE q1 FROM @a;
EXECUTE q1;
DEALLOCATE PREPARE q1;
To cleanup after the last V1 instance is removed:
SELECT IF (EXISTS(SELECT 1
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'Exceptions'
AND COLUMN_NAME = 'SQL')
,'ALTER TABLE `Exceptions` DROP COLUMN `SQL`;'
,'Select ''Already Gone''')
INTO @a;
PREPARE q1 FROM @a;
EXECUTE q1;
DEALLOCATE PREPARE q1;