Close and dispose of resources before displaying error messages? - error-handling

Is it good practice to close and dispose of resources before displaying error messages?
If you are catching errors and you display an error message in the same scope as resources such as database and file objects, then shouldn't these resources be closed and disposed of before the error message is displayed?
If you are waiting for these resources to drop out of scope then they will only do this once the error message dialog is closed. This means that a user could leave the error message on the screen for some time and in doing so keep a lock on some resources.
eg.
try { ... }
catch (Exception e) {
// should close/dispose resources here
...
...
MessageBox("Error");
}

Preferably, don't display any UI in the catch block. Instead, dispose of the resources in the finally block, but return some value that indicates that an error occurred and have the calling method handle it, with UI if necessary.
A variation of that would be to dispose of the resources in the finally block and have the catch block rethrow the exception for the calling method to handle.

Better to be putting your resources in a
using( ) { } scope
or use RAII, so as they drop out of scope they are tidied up correctly before the messagebox is hit.

You could try using the finally block.
http://msdn.microsoft.com/en-us/library/zwc8s4fz.aspx

Related

single() and first() terminal operators when producer emits many values

I need to collect only the first value from two emitted by flow.
I have a function that returns flow:
fun myFlow = flow {
try {
emit(localDataSource.fetchData())
} catch(e: Exception) {
// just skip this error
}
emit(remoteDataSource.fetchData(1000, 0))
}
In one special case I need only first emitted value, doesn't matter is it from local cache or remote source.
I tried this one:
fun getRandomFavoriteItem() = myFlow.first().filter { it.score > 7 }.randomOrNull()
But first() invocation always throws
java.lang.IllegalStateException: Flow exception transparency is violated:
Previous 'emit' call has thrown exception kotlinx.coroutines.flow.internal.AbortFlowException: Flow was aborted, no more elements needed, but then emission attempt of value.
What I've tried:
single() -
java.lang.IllegalArgumentException: Flow has more than one element
take(1).first() -
java.lang.IllegalStateException: Flow exception transparency is violated:
Previous 'emit' call has thrown exception kotlinx.coroutines.flow.internal.AbortFlowException: Flow was aborted, no more elements needed, but then emission attempt of value
Catch error but it doesn't stop here:
myFlow.catch { e ->
if (e !is IllegalArgumentException) {
throw e
}
}.first().filter { it.score > 7 }.randomOrNull()
My questions are:
What is the point of usage first() if it doesn't work in case of more than 1 emitted values? If I would know that my flow produces only one value I could just use any other terminal operator.
How to avoid those errors and how to collect only first value without adding repeated code?
This isn't an error in first(). It's an error in your flow. You are not permitted to swallow all exceptions in a Flow in the way you have.
Some varying approaches may differ in whether they detect that error, but what you must fix is how you "just skip" all exceptions. Consider catching only the specific exceptions you're concerned about, or at least making sure to catch and rethrow CancellationException or its subclasses.
Lous Wasserman already found the problem, here some more details.
As mentioned in the error message you're also catching the AbortFlowException.
java.lang.IllegalStateException: Flow exception transparency is
violated: Previous 'emit' call has thrown exception
kotlinx.coroutines.flow.internal.AbortFlowException: Flow was aborted,
no more elements needed, but then emission attempt of value.
You're bascically catching an exception which interferes with the way flows work. The problem is not about the first function.
Since AbortFlowException is internal you cannot access it, but you can access its superclass CancellationException. You need to modify your catch block like this:
try {
emit(localDataSource.fetchData())
} catch (e: Exception) {
if(e is CancellationException) {
throw e
}
}
Now first will work in the way you expect it to.
Edit:
A better solution would be to handle the exception within fetchData (you might return null in case one was thrown). This way you don't get in the way of the flow mechanics.
If that is not possible, you could create a wrapper function which takes care of the exception handling.

Proper way to send Web API response

I read somewhere that TRY CATCH is not recommended in Web API methods.
I'm making the following call into a method and if all goes well, I want to return an Employee object along with Status 200 but if something goes wrong e.g. database call fails, etc. I want to return status 500. What's the right way to handle that code?
[HttpPost]
public async Task<IHttpActionResult> PostNewEmployeeAsync(Employee emp)
{
var newEmployee = await RegisterEmployee(emp);
return Ok(emp);
// What if I had a database error in RegisterEmployee method. How do I detect the error and send InternalServerError()
}
private async Task<Employee> RegisterEmployee(Employee emp)
{
// Call DB to register new employee, then return Employee object
}
Your code should return the error code that matches the case that you have, for example if your code couldn't find the required resource in the database return NotFound,
but if you code raises an exception, avoid wrapping your code by try/catch block and instead the exception should bubble up to the level that you can handle it globally, to do this you have many options like :
1- Implement an ExceptionFilter where you can handle all the unhandled exceptions raised in your controllers (this doesn't include any exception happens before the controllers in the pipeline).
See this for more details about ExceptionFilterAttribute.
2- If you are using Web API 2, you can implement the interface IExceptionHandler where you can handle all the exception happens anywhere in the pipeline and there you can return the errors you want.
See this for more details about Global Exception Handling in Web API 2.
Hope that helps.
You don't want to avoid try/catch entirely, you just need to be really careful about it. Wrap your code in a try block, and catch the exception you're expecting. Inside the catch, return the error response.

Handling Windows Store App exceptions from GetFileAsync

I have a problem with the following code example:
Windows::Storage::StorageFolder^ location = Package::Current->InstalledLocation;
try
{
task<StorageFile^> GetFileTask(location->GetFileAsync(sn));
GetFileTask.then([=](StorageFile^ file)
{
try
{
task<IBuffer^> ReadFileTask(FileIO::ReadBufferAsync(file));
ReadFileTask.then([=](IBuffer^ readBuffer)
{
// process file contents here
});
}
catch(Platform::Exception^ ex)
{
// Handle error here
}
});
}
catch(Platform::Exception^ ex)
{
// Handle error here
}
When using a filename that doesn't exist the function throws an exception:
Unhandled exception at 0x0FFCC531 (msvcr110d.dll) in GameTest2.exe: An invalid parameter was passed to a function that considers invalid parameters fatal.
I've been searching the internet and this exception breaks only when connected to the debugger. I'm using VS 2012. I've turned off all the relevant 'break on exception' but it still causes the debugger to break and non of my handlers are getting a chance to handle the exception.
If the file is missing I would expect the GetFileAsync method to throw a 'File doesn't exist' exception. Not sure why it keeps throwing the 'Invalid parameter' exception.
This is starting to bother me and I just can't find any known solution to this issue. Anyone have any ideas?
I'm going to try and change the method to not use the task<> code. Instead I'll call the GetFileAsync using 'await'. However I believe 'await' will just cause the calling thread to wait until the GetFileAsync has finished, which kind of defeats the point of asynchronous loading.
I'm wondering if this is a common issue with exception handling when using tasks.
Update:
OK, I've now found the solution:
task<StorageFile^>( location->GetFileAsync(sn)).then([](StorageFile^ openedFile)
{
return FileIO::ReadBufferAsync(openedFile);
}).then([](IBuffer^ readBuffer)
{
// Process file
}).then([](task<void> t)
{
try
{
t.get();
}
catch(Platform::Exception^ e)
{
// Handle error
}
});
It seems there needs to be an extra 'then' condition added to the end of the chain to pick up the exception.

InvalidOperationException is ignored in try/catch block

I have the following coding
try
{
var foundCanProperty = properties
.First(x => x.Name == "Can" + method.Name);
var foundOnExecuteMethod = methods
.First(x => x.Name == "On" + method.Name);
var command = new Command(this, foundOnExecuteMethod, foundCanProperty);
TrySetCommand(foundControl as Control, command);
}
catch (InvalidOperationException ex)
{
throw new FatalException("Please check if you have provided all 'On' and 'Can' methods/properties for the view" + View.GetType().FullName, ex);
}
I'd expected that if the methods.First() (in second var statement) throws an InvalidOperationException, I'd be able to catch it. But this seems not be the case (catch block is ignored and the application terminates with the raised exception). If I throw myself an exception of the same type within the try block, it gets caught. Does Linq use multihreading so that the exception is thrown in another thread? Perhaps I make also a stupid error here and just do not see it :(.
Thanks for any help!
I know that this isn't an answer, but rather some additional steps for debugging, but does it change anything if you instead try to catch the general type "Exception" instead of the IOE? That may help to isolate if the method is truly throwing an IOE, or if its failure is generating an IOE somewhere else in the stack. Also - assuming this method isn't in main() - is there a way to wrap the call to it in a try/catch and then inspect the behavior at that point in the call flow?
Apologies, too, in that I know very little about the SilverLight development environment so hopefully the suggestions aren't far fetched.
InvalidOperationException exception occures when The source sequence is empty.
refere to http://msdn.microsoft.com/en-us/library/bb291976.aspx
check weather "properties" or "methods" is not empty.
out of interest, Why you not using FirstOrDefault ?

Error Handling in WCF Service

With the following service method example:-
[PrincipalPermission(SecurityAction.Demand, Role="BUILTIN\\Administrator")]
public string GetTest()
{
try
{
return "Hello";
}
catch (Exception ex)
{
throw ex;
}
}
How do I get an error from the method when the caller is not in the correct Role. In design time the error breaks on the method line (i.e. public string GetTest) and does not reach the catch. At run time it is reported in my silverlight application as an unhandled error (I have try.. catch blocks there too).
There doesn't seem to be a place to catch the error as it never gets into the try blocks!!
The check for the role is made (by the WCF runtime) before the method is actually called - not inside the method!
You need to handle this exception on the caller's side when you make this call.
If you need to check certain conditions inside your service code, don't decorate the method with an attribute, but instead use the role provider in code to check for a given condition.
If you want global error handler for your WCF service you can implement IErrorHandler and add it in custom behavior. Operation can't catch exceptions thrown outside of its try block.