Fixes #76 - improve error messages in Hosting

Removed the TODOs from messages, and generally made them more readable.
This commit is contained in:
Eilon Lipton 2015-03-01 22:55:27 -08:00
parent 6bf5eabd9f
commit 16c8d51d0b
5 changed files with 65 additions and 25 deletions

View File

@ -67,7 +67,7 @@ namespace Microsoft.AspNet.Hosting
catch (Exception ex)
{
var logger = loggerFactory.Create<Program>();
logger.WriteError("TODO: Dispose threw an exception", ex);
logger.WriteError("Dispose threw an exception.", ex);
}
shutdownHandle.Set();
});

View File

@ -32,7 +32,7 @@ namespace Microsoft.AspNet.Hosting.Server
var assembly = Assembly.Load(new AssemblyName(assemblyName));
if (assembly == null)
{
throw new Exception(String.Format("TODO: assembly {0} failed to load message", assemblyName));
throw new Exception(string.Format("The assembly {0} failed to load.", assemblyName));
}
Type type = null;
@ -50,7 +50,7 @@ namespace Microsoft.AspNet.Hosting.Server
if (type == null)
{
throw new Exception(String.Format("TODO: type {0} failed to load message", typeName ?? "<null>"));
throw new Exception(string.Format("The type {0} failed to load.", typeName ?? "<null>"));
}
}
else
@ -59,14 +59,14 @@ namespace Microsoft.AspNet.Hosting.Server
if (type == null)
{
throw new Exception(String.Format("TODO: type {0} failed to load message", typeName ?? "<null>"));
throw new Exception(String.Format("The type {0} failed to load.", typeName ?? "<null>"));
}
interfaceInfo = type.GetTypeInfo().ImplementedInterfaces.FirstOrDefault(interf => interf.Equals(typeof(IServerFactory)));
if (interfaceInfo == null)
{
throw new Exception("TODO: IServerFactory interface not found");
throw new Exception(string.Format("The type '{0}' does not implement the '{1}' interface.", type, typeof(IServerFactory).FullName));
}
}

View File

@ -31,9 +31,10 @@ namespace Microsoft.AspNet.Hosting.Startup
{
if (required)
{
throw new Exception(string.Format("TODO: {0} or {1} method not found",
throw new Exception(string.Format("A method named '{0}' or '{1}' in the type '{2}' could not be found.",
methodNameWithEnv,
methodNameWithNoEnv));
methodNameWithNoEnv,
startupType.FullName));
}
return null;
@ -42,8 +43,10 @@ namespace Microsoft.AspNet.Hosting.Startup
{
if (required)
{
throw new Exception(string.Format("TODO: {0} method does not return " + returnType.Name,
methodInfo.Name));
throw new Exception(string.Format("The '{0}' method in the type '{1}' must have a return type of '{2}'.",
methodInfo.Name,
startupType.FullName,
returnType.Name));
}
return null;
}
@ -75,10 +78,11 @@ namespace Microsoft.AspNet.Hosting.Startup
catch (Exception)
{
throw new Exception(string.Format(
"TODO: Unable to resolve service for {0} method {1} {2}",
methodInfo.Name,
"Could not resolve a service of type '{0}' for the parameter '{1}' of method '{2}' on type '{3}'.",
parameterInfo.ParameterType.FullName,
parameterInfo.Name,
parameterInfo.ParameterType.FullName));
methodInfo.Name,
methodInfo.DeclaringType.FullName));
}
}
}
@ -98,26 +102,26 @@ namespace Microsoft.AspNet.Hosting.Startup
var assembly = Assembly.Load(new AssemblyName(applicationName));
if (assembly == null)
{
throw new Exception(String.Format("TODO: assembly {0} failed to load message", applicationName));
throw new Exception(String.Format("The assembly '{0}' failed to load.", applicationName));
}
var startupName1 = "Startup" + environmentName;
var startupName2 = "Startup";
var startupNameWithEnv = "Startup" + environmentName;
var startupNameWithoutEnv = "Startup";
// Check the most likely places first
var type =
assembly.GetType(startupName1) ??
assembly.GetType(applicationName + "." + startupName1) ??
assembly.GetType(startupName2) ??
assembly.GetType(applicationName + "." + startupName2);
assembly.GetType(startupNameWithEnv) ??
assembly.GetType(applicationName + "." + startupNameWithEnv) ??
assembly.GetType(startupNameWithoutEnv) ??
assembly.GetType(applicationName + "." + startupNameWithoutEnv);
if (type == null)
{
// Full scan
var definedTypes = assembly.DefinedTypes.ToList();
var startupType1 = definedTypes.Where(info => info.Name.Equals(startupName1, StringComparison.Ordinal));
var startupType2 = definedTypes.Where(info => info.Name.Equals(startupName2, StringComparison.Ordinal));
var startupType1 = definedTypes.Where(info => info.Name.Equals(startupNameWithEnv, StringComparison.Ordinal));
var startupType2 = definedTypes.Where(info => info.Name.Equals(startupNameWithoutEnv, StringComparison.Ordinal));
var typeInfo = startupType1.Concat(startupType2).FirstOrDefault();
if (typeInfo != null)
@ -128,9 +132,9 @@ namespace Microsoft.AspNet.Hosting.Startup
if (type == null)
{
throw new Exception(String.Format("TODO: {0} or {1} class not found in assembly {2}",
startupName1,
startupName2,
throw new Exception(String.Format("A type named '{0}' or '{1}' could not be found in assembly '{2}'.",
startupNameWithEnv,
startupNameWithoutEnv,
applicationName));
}

View File

@ -0,0 +1,18 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNet.Builder;
namespace Microsoft.AspNet.Hosting.Fakes
{
public class StartupWithConfigureServicesNotResolved
{
public StartupWithConfigureServicesNotResolved()
{
}
public void Configure(IApplicationBuilder builder, int notAService)
{
}
}
}

View File

@ -114,7 +114,25 @@ namespace Microsoft.AspNet.Hosting.Tests
var diagnosticMessages = new List<string>();
var ex = Assert.Throws<Exception>(() => loader.LoadStartup("Microsoft.AspNet.Hosting.Tests", "Boom", diagnosticMessages));
Assert.True(ex.Message.Contains("ConfigureBoom or Configure method not found"));
Assert.Equal("A method named 'ConfigureBoom' or 'Configure' in the type 'Microsoft.AspNet.Hosting.Fakes.StartupBoom' could not be found.", ex.Message);
}
[Fact]
public void StartupWithConfigureServicesNotResolvedThrows()
{
var serviceCollection = HostingServices.Create();
var services = serviceCollection.BuildServiceProvider();
var loader = services.GetRequiredService<IStartupLoader>();
var diagnosticMessages = new List<string>();
var startup = loader.LoadStartup("Microsoft.AspNet.Hosting.Tests", "WithConfigureServicesNotResolved", diagnosticMessages);
var app = new ApplicationBuilder(services);
var ex = Assert.Throws<Exception>(() => startup.Invoke(app));
Assert.Equal("Could not resolve a service of type 'System.Int32' for the parameter 'notAService' of method 'Configure' on type 'Microsoft.AspNet.Hosting.Fakes.StartupWithConfigureServicesNotResolved'.", ex.Message);
}
[Fact]