I want to test a repository against some erronous network behavior. I faked the class using MS Fakes and it looks like this:
ShimInputRepository
.AllInstances
.UpdateEngagementStringNullableOfInt64NullableOfInt32String = (xInst, xEngId, xTrimUri, xTargetVers, xComments) =>
{
if (xEngId != initializer.SeededEngagementsWithoutEmp[3].EngagementId)
{
return xInst.UpdateEngagement(xEngId, xTrimUri, xTargetVers, xComments); //Unfortunately, calls recursively same method (not the original one)
}
else
{
throw new Exception
(
"An error occurred while executing the command definition. See the inner exception for details.",
new Exception
(
"A transport-level error has occurred when receiving results from the server. (provider: Session Provider, error: 19 - Physical connection is not usable)"
)
);
}
};
I don't know how to call the original method from withing that code (currently it recursively calls same method).
How to call the original method?
UPDATE: What I really want to achieve is to throw an exception on a specific call to this method (the "if() ..." statement) and forward the call to original instance otherwise.
The Fakes framework provides support for just such an occasion. You can use:
ShimInputRepository
.AllInstances
.UpdateEngagementStringNullableOfInt64NullableOfInt32String = (xInst, xEngId, xTrimUri, xTargetVers, xComments) =>
{
if (xEngId != initializer.SeededEngagementsWithoutEmp[3].EngagementId)
{
return ShimsContext.ExecuteWithoutShims(() => xInst.UpdateEngagement(xEngId, xTrimUri, xTargetVers, xComments));
}
else
{
throw new Exception
(
"An error occurred while executing the command definition. See the inner exception for details.",
new Exception
(
"A transport-level error has occurred when receiving results from the server. (provider: Session Provider, error: 19 - Physical connection is not usable)"
)
);
}
};
The ShimsContext.ExecuteWithoutShims method will execute the Func< T > outside of the current shim context (e.g. without the shim redirection which was causing you your infinite loop).
The cause of your infinite loop is that creating a ShimContext modifies your assembly at runtime. As long as the context is active, all invocations of the shimmed method are redirected to the static method on the shim class. You need to explicitly go outside the shim context for the portion of code you want to execute as normal.
Related
According to the documentation here: https://learn.microsoft.com/en-us/dotnet/api/system.serviceprocess.servicecontroller.servicename?view=dotnet-plat-ext-7.0#exceptions
The ServiceController.ServiceName will throw an InvalidOperationException if "The service was not found."
But running this code, it runs without throwing an exception:
var serviceController = new ServiceController();
serviceController.ServiceName = "Not.Existing.Service";
I, personally, don't believe this check on the service status happens upon setting the ServiceName (on the creation of the ServiceControler object). But the documentation is not clear when the exception is thrown exactly on this property.
There's also a possibility that the exception is thrown on getting the value from the ServiceName, I tried the following scenario:
Installed a service
Ran the code (below)
Paused the debugger on line 3
Uninstalled the service
Continued running the code
No exception occurred!
/*1*/ serviceController.ServiceName = "Existing.Service";
/*2*/ serviceController.Start();
/*3*/ var serviceName = serviceController.ServiceName;
I also found other questions (this one) that none of the answers mention this property when checking whether a Windows service is installed or not.
Note: my problem is not trying to figure out how to check whether a Windows service is installed or not, but to understand when the exception is thrown on the ServiceName property.
You'll need to use the constructor with string argument to make (an attempt to make) a link with an existing service.
Initializes a new instance of the ServiceController class that is associated with an existing service on the local computer.
The constructor will not throw an exception in case the service does not exist, but accessing that ServiceName property get will throw one as documented.
Below example throws that exception.
var serviceController = new ServiceController("Not.Existing.Service");
var serviceName = serviceController.ServiceName; // << Exception thrown.
If you look at the source code here you will see when this exception is thrown. There are several opportunities for ServiceController to throw this exception on the service name. Specifically, look in the private void GenerateNames() definition. This function is only called in the getters for ServiceName and DisplayName and that's when you'll probably encounter this exception.
If you read this code, it is clearly mentioned that it does not throw exceptions for invalid service names (It does only validation check) on the setter of ServiceController's ServiceName
I'm using EmbedIO with the Web API module.
I'd like to have an exception handler that will catch all the unhandled exceptions and return a suited HTTP error code according to the exception type. However, it's not clear if this can be achieved.
The class WebModuleBase exposes a property called OnUnhandledException that can be set to an ExceptionHandlerCallback, but when the callback is invoked, the response's status code has already been set to HttpStatusCode.InternalServerError, as stated in the code comments.
This is not convenient since I want to set the response code myself.
WebModuleBase exposes a different property called OnHttpException that can be set to a HttpExceptionHandlerCallback. This can be set to
HttpExceptionHandler.DataResponse(ResponseSerializer.Json) which partially solves the issue.
The main concern now is that the application exceptions must be converted to HttpException in the controllers.
I'd like to throw custom exceptions from the domain code, get them in an exception handler and just return a HTTPException in there, according to the initial exception.
Basically something similar to Exception Filters in ASP.NET Web API.
Here's the code to setup the web server:
var webApiModule = new WebApiModule("/api", ResponseSerializer.Json)
.WithController<MyController>();
webApiModule.OnUnhandledException = ExceptionHandler.DataResponseForException();
webApiModule.OnHttpException = ExceptionHandler.DataResponseForHttpException();
WebServerEmbedded = new EmbedIO.WebServer(
opt => opt
.WithUrlPrefix(url)
.WithMode(HttpListenerMode.EmbedIO))
.WithModule(null, webApiModule);
These are the delegates used for exception handlers:
internal static class ExceptionHandler
{
public static ExceptionHandlerCallback DataResponseForException()
{
return (context, exception) => ResponseSerializer.Json(context, exception.Message);
}
public static HttpExceptionHandlerCallback DataResponseForHttpException()
{
return (context, httpException) => ResponseSerializer.Json(context, httpException.Message);
}
}
Thanks.
Exceptions, as well as HTTP exceptions, are handled by EmbedIO at both module and server level (each nested module group introduces a further level, but that's beyond the point).
The catch clause for HTTP exceptions always comes before the "general-purpose" catch clause, for the obvious reason that HTTP exceptions are exceptions themselves and need to be sorted out. Therefore, if an exception handler throws a HTTP exception, the latter must be handled at an outer level.
In opther words, you can write a module-level exception handler that throws a HTTP exception, then use a server-level HTTP exception handler to generate the appropriate response.
var webApiModule = new WebApiModule("/api", ResponseSerializer.Json)
.WithController<MyController>()
.HandleUnhandledException(ExceptionHandler.DataResponseForException));
WebServerEmbedded = new EmbedIO.WebServer(
opt => opt
.WithUrlPrefix(url)
.WithMode(HttpListenerMode.EmbedIO))
.WithModule(webApiModule)
.HandleHttpException(ExceptionHandler.DataResponseForHttpException);
internal static class ExceptionHandler
{
public static Task DataResponseForException(IHttpContext context, Exception exception)
{
// Replace ANY_VALID_STATUS CODE with, well, any valid status code.
// Of course you can use different status codes according to, for example,
// the type of exception.
throw new HttpException(ANY_VALID_STATUS_CODE, exception.Message);
}
public static Task DataResponseForHttpException(IHttpContext context, IHttpException httpException)
{
context.Response.StatusCode = (int)HttpStatusCode.OK;
return ResponseSerializer.Json(context, httpException.Message);
}
}
EDIT: There's an even simpler way, if you need it for custom exceptions: just have your exceptions implement IHttpException.
Here you can see how IHttpException methods are used by the HTTP exception handling code.
Here is an example of probably the most obscure method, PrepareResponse.
EDIT: I added setting the status code in DataResponseForHttpException.
I run into troubles using the Roslyn Scripting Engine. I get no exception handling when I run a script within a delegation.
Test that works as expected:
string script = #"var a=0; var b=2/a;";
var runner = CSharpScript.Create<object>(script);
var errors = runner.Compile();
Assert.IsTrue(errors.IsEmpty);
try
{
runner.RunAsync();
Assert.Fail("Where is the exception");
}
catch (System.Exception)
{
// everything is OK! Error thrown...
}
Result: No Assertion. The Exception was thrown.
Here's the text using a delegate object:
Unittest:
string script = #"var a=0; var b=2/a;";
var runner = CSharpScript.Create<object>(script);
var errors = runner.Compile();
var delegat = runner.CreateDelegate();
Assert.IsTrue(errors.IsEmpty);
try
{
delegat();
Assert.Fail("Where is the exception?");
}
catch (System.DivideByZeroException)
{
// everything is OK! Error thrown...
}
I got the fail message and no exception was thrown.
We cache the delegates to speed up the compilation and during a test we see that runtime exceptions are not thrown. So I wrote the test to reproduce this situation.
I can't find any hint in the docs which describes that there are no exceptions thrown during the invoke.
Can someone give me a pointer or a hint why this happens?
There are two issues with your code:
In the first version, you're catching Exception, which means that when the Assert.Fail is reached and throws AssertionException, that exception is then caught and ignored.
This means that there is no difference between RunAsync and delegate here, neither of them throws DivideByZeroException.
Both RunAsync and the ScriptRunner<T> delegate return Task. That means to actually wait for them to complete or to observe any exceptions, you need to use await. Once you do that, you will see the DivideByZeroException that you're expecting.
Your Main finishes execution before the scheduler gets a chance to invoke delegat. It is a task that will run asynchronously. You can see that when you inspect it in the debugger:
To force execution inside the scope of the try...catch, you can use this:
try
{
delegat().Wait();
}
catch(System.AggregateException ex)
{
/* the inner exception of ex will be your DivideByZeroException */
}
The correct type of exception to expect in this case is the AggregateException, see here why.
A solution with await is also possible:
await delegat();
but this will compile only when the containing method can be marked async which is not necessarily what you want (show more of the calling code to clarify).
I have a WCF service that throws FaultExceptions when something goes wrong. Some of the error classes being thrown works just fine, yet some of the other doesn't work at all and give the following error:
An error occured while receiving the HTTP response to http://localhost/MyService. This could be due to the service endpoint binding not using the HTTP protocol. This could also be due to an HTTP request context being aborted by the server (possibly due to the service shutting down).
With an inner exception saying
The underlying connection was closed: An unexpected error occurred on a receive.
My code works thusly:
Server
public Stream DoSomething() {
if (someCondition) {
if (fileExists) {
return new Stream(); // I know I can't do this, but for example purpose only :)
}
throw new FaultException<System.IO.FileNotFoundException>(new FileNotFoundException());
}
throw new FaultException<MyException>(new MyException());
}
Exception class
public class MyException: Exception
{
}
Client
try {
wcfClient.DoSomething();
} catch (FaultException<FileNotFoundException>) {
// This works just fine
} catch (FaultException<MyException>) {
// This gives the error listed above
}
Both FileNotFoundException and MyException are set up in the contract:
[FaultContract(typeof(FileNotFoundException))]
[FaultContract(typeof(MyException))]
Why does FaultException<FileNotFoundException> work as expected, but not FaultException<MyException>?
If I remove Exception inheritance from MyException everything works as it should (but I want consistency, so I want it to be an actual exception). There is no change if Exception inheritance is left in, but it is decorated with [DataContract].
Why is that? FileNotFoundException inherits from Exception too. One works, the other doesn't. Frustrating!
P.S.: Both the server and the client share the same assembly the interfaces and classes are defined in, so there shouldn't be any contract mismatches.
Your exception should probably be [Serializable]. I think that would solve your problem already.
As a best practice for Exceptions you should also implement the three constructors.
I'm running into this issue where I get the following error:
A first chance exception of type 'System.ObjectDisposedException' occurred in EntityFramework.dll
Additional information: The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.
I get that error while trying to access a table using EF 6. I have set the method to async and await the return value, but it still gives me disposed error.
public async Task<List<Ticket>> GetAllOpenTwoTicketsAsync() {
using (AssetTrackingEntitiesObj _edmObj = new AssetTrackingEntitiesObj()) {
_edmObj.FullObjectContext.Connection.Open();
return await _edmObj.Tickets
.Where(t => t.TicketStatusType.isOpenTicket)
.Include(t => t.AssetTickets)
.Select(t => t).ToListAsync();
}
}
here is the method that calls the tickets
TicketsCollection = new ObservableCollection<Ticket>(await _ticketRepository.GetAllOpenTwoTicketsAsync());
Am I doing that correctly? Every method in my repository uses a using statement, creates its own objectcontext, opens its own connection and then does what ever it needs to, is this the correct manner for multiple async with EF6? Thanks in advance.
_edmObj.FullObjectContext.Connection.Open(); isn't needed. The using statement takes care of opening and disposing the context. That's the main reason to use them over opening/closing/disposing resources yourself.
.Select(t => t) is completely unnecessary. Just calling ToListAsync() will do the trick.
The rest of your code looks fine, so it's probably the first statement that is causing the error. Another cause could be that you try to access a navigation property that you didn't include, lazy loading doesn't work when your context is disposed.