I am new to the functional style of programming using vavr.
I have a method returns the data when its executed successfully and if it fails, it returns the MyCustomRunTimeException.
In my Service class, I am calling this API method, when API method fails I have to catch the exception and going to clear my application cache and return the same exception to the caller (another service method in my case).
if method call success I have to return the actual object, not the Try wrapped object.
How can I achieve this using vavr Try?
I tried to use different methods in vavr Try.recover but I am unable to throw the same exception.
Any sample example or snippet could be very helpful for me if some can provide.
Thanks in advance.
Example:
Foo doFoo() {
throw new MyCustomRunTimeException();
}
method1(){
try{
doFoo();
}catch(MyCustomRunTimeException ex){
clearcache();
throw ex;
}
}
Basically, if your function throws, you want to do something (in case of failure) then throw it again?
How about this?
Foo doFoo() {
throw new MyCustomRunTimeException();
}
Foo myService() {
return Try.of(() -> doFoo())
.onFailure(e -> clearCache())
.getOrElseThrow(identity());
}
If I may: since you want to try functional style, we usually don't rely on exceptions in FP, instead we rely on types that represent possibility of failure, like Either<MyBusinessProblem, Foo>.
Then your code would look like:
Either<MyBusinessProblem, Foo> doFoo() {
return Left.of(new MyBusinessProblem());
}
Either<MyBusinessProblem, Foo> doFoo() myService() {
return doFoo()
.peekLeft(businessProblem -> clearCache());
}
As a bonus, now your code is explicit and you don't risk forgetting handling an error.
Related
Is there any scenario where writing method like this:
public async Task<SomeResult> DoSomethingAsync()
{
// Some synchronous code might or might not be here... //
return await DoAnotherThingAsync();
}
instead of this:
public Task<SomeResult> DoSomethingAsync()
{
// Some synchronous code might or might not be here... //
return DoAnotherThingAsync();
}
would make sense?
Why use return await construct when you can directly return Task<T> from the inner DoAnotherThingAsync() invocation?
I see code with return await in so many places, I think I might have missed something. But as far as I understand, not using async/await keywords in this case and directly returning the Task would be functionally equivalent. Why add additional overhead of additional await layer?
There is one sneaky case when return in normal method and return await in async method behave differently: when combined with using (or, more generally, any return await in a try block).
Consider these two versions of a method:
Task<SomeResult> DoSomethingAsync()
{
using (var foo = new Foo())
{
return foo.DoAnotherThingAsync();
}
}
async Task<SomeResult> DoSomethingAsync()
{
using (var foo = new Foo())
{
return await foo.DoAnotherThingAsync();
}
}
The first method will Dispose() the Foo object as soon as the DoAnotherThingAsync() method returns, which is likely long before it actually completes. This means the first version is probably buggy (because Foo is disposed too soon), while the second version will work fine.
If you don't need async (i.e., you can return the Task directly), then don't use async.
There are some situations where return await is useful, like if you have two asynchronous operations to do:
var intermediate = await FirstAsync();
return await SecondAwait(intermediate);
For more on async performance, see Stephen Toub's MSDN article and video on the topic.
Update: I've written a blog post that goes into much more detail.
The only reason you'd want to do it is if there is some other await in the earlier code, or if you're in some way manipulating the result before returning it. Another way in which that might be happening is through a try/catch that changes how exceptions are handled. If you aren't doing any of that then you're right, there's no reason to add the overhead of making the method async.
Another case you may need to await the result is this one:
async Task<IFoo> GetIFooAsync()
{
return await GetFooAsync();
}
async Task<Foo> GetFooAsync()
{
var foo = await CreateFooAsync();
await foo.InitializeAsync();
return foo;
}
In this case, GetIFooAsync() must await the result of GetFooAsync because the type of T is different between the two methods and Task<Foo> is not directly assignable to Task<IFoo>. But if you await the result, it just becomes Foo which is directly assignable to IFoo. Then the async method just repackages the result inside Task<IFoo> and away you go.
If you won't use return await you could ruin your stack trace while debugging or when it's printed in the logs on exceptions.
When you return the task, the method fulfilled its purpose and it's out of the call stack.
When you use return await you're leaving it in the call stack.
For example:
Call stack when using await:
A awaiting the task from B => B awaiting the task from C
Call stack when not using await:
A awaiting the task from C, which B has returned.
Making the otherwise simple "thunk" method async creates an async state machine in memory whereas the non-async one doesn't. While that can often point folks at using the non-async version because it's more efficient (which is true) it also means that in the event of a hang, you have no evidence that that method is involved in the "return/continuation stack" which sometimes makes it more difficult to understand the hang.
So yes, when perf isn't critical (and it usually isn't) I'll throw async on all these thunk methods so that I have the async state machine to help me diagnose hangs later, and also to help ensure that if those thunk methods ever evolve over time, they'll be sure to return faulted tasks instead of throw.
This also confuses me and I feel that the previous answers overlooked your actual question:
Why use return await construct when you can directly return Task from the inner DoAnotherThingAsync() invocation?
Well sometimes you actually want a Task<SomeType>, but most time you actually want an instance of SomeType, that is, the result from the task.
From your code:
async Task<SomeResult> DoSomethingAsync()
{
using (var foo = new Foo())
{
return await foo.DoAnotherThingAsync();
}
}
A person unfamiliar with the syntax (me, for example) might think that this method should return a Task<SomeResult>, but since it is marked with async, it means that its actual return type is SomeResult.
If you just use return foo.DoAnotherThingAsync(), you'd be returning a Task, which wouldn't compile. The correct way is to return the result of the task, so the return await.
Another reason for why you may want to return await: The await syntax lets you avoid hitting a mismatch between Task<T> and ValueTask<T> types. For example, the code below works even though SubTask method returns Task<T> but its caller returns ValueTask<T>.
async Task<T> SubTask()
{
...
}
async ValueTask<T> DoSomething()
{
await UnimportantTask();
return await SubTask();
}
If you skip await on the DoSomething() line, you'll get a compiler error CS0029:
Cannot implicitly convert type 'System.Threading.Tasks.Task<BlaBla>' to 'System.Threading.Tasks.ValueTask<BlaBla>'.
You'll get CS0030 too, if you try to explicitly typecast it.
This is .NET Framework, by the way. I can totally foresee a comment saying "that's fixed in .NET hypothetical_version", I haven't tested it. :)
Another problem with non-await method is sometimes you cannot implicitly cast the return type, especially with Task<IEnumerable<T>>:
async Task<List<string>> GetListAsync(string foo) => new();
// This method works
async Task<IEnumerable<string>> GetMyList() => await GetListAsync("myFoo");
// This won't work
Task<IEnumerable<string>> GetMyListNoAsync() => GetListAsync("myFoo");
The error:
Cannot implicitly convert type 'System.Threading.Tasks.Task<System.Collections.Generic.List>' to 'System.Threading.Tasks.Task<System.Collections.Generic.IEnumerable>'
Consider the following code
import 'dart:async';
Future main() async {
try {
print("trying");
await doSomething();
print("success");
} catch (e) {
print("caught");
}
}
Future<int> doSomething() async {
await doSomethingElse();
return 5;
}
Future<int> doSomethingElse() async {
throw new Exception();
}
When run, the exception thrown in doSomethingElse() is caught up in main(), and everything works as expected. But, say the person who wrote the doSomething() method didn't realize that doSomethingElse() was asynchronous, and instead wrote the follow (note the missing await).
Future<int> doSomething() async {
doSomethingElse();
return 5;
}
Now the exception isn't caught at all. Rather, the output now looks like this:
trying
success
Unhandled exception:
Uncaught Error: Exception
Stack Trace:
#0 doSomethingElse.<doSomethingElse_async_body> (file:///C:/code/test.dart:19:7)
#1 Future.Future.<anonymous closure> (dart:async/future.dart:118)
<snip>
What's happening is that doSomething() is returning immediately, and then sometime later, in another context, doSomethingElse() is throwing its error, stopping all execution immediately. I know that an answer to this might be "Well, don't do that then." but I'm considering cases where I might not have control over the methods I'm calling (say if they are part of a library).
This situation leads to a couple of related questions:
As the author of main(), is there any way I can be certain that my call to doSomething() won't end with an unhandled exception? Or am I dependent on the author of doSomething() to make sure all possible exceptions are handled or propagated to the returned Future? Is there a way to attach some sort of global error handler that can catch errors from abandoned Futures?
As the author of doSomething(), if I don't want to wait on doSomethingElse() (say it writes to a log for example, so I neither need the output nor do I need to worry about handling errors). Is there anything I can do to prevent errors in doSomethingElse() from halting the program other than wrapping every call of it a try/catch block (which can be cumbersome an easily overlooked)?
As the author of doSomethingElse(), is there some pattern I can use which allows me to throw Exceptions in a way that callers who wait for the Future to complete can handle that Exception themselves whereas callers that don't wait for the Future don't have to worry about catching the Exception? My best thought in that regard is to return a special object rather than throwing an Exception, but that adds a lot of extra cruft and makes the method much harder use.
Note: I'm using async/await syntax here, but the question should be equally relevant for a more strictly Future based construction (where you return a new Future in doSomething() instead of .then()ing off the one from doSomethingElse()
Uncaught asynchronous errors are handled to the current zone's error handler.
What you are seeing is the root-zone's error handler reporting the error as uncaught, which also terminates the isolate.
What you want is to introduce a different error handler for your code, by running it through runZoned with an error handler:
import "dart:async";
main() {
runZoned(() async {
try {
print("trying");
await doSomething();
print("success");
} catch (e) {
print("caught");
}
}, onError: (e, s) {
print("uncaught");
});
}
Like Greg pointed in its comment you can use Zones to catch unexpected errors from async code.
My page calls a Services layer method that uses a Generic Repository "Find" method. In the services layer method, I do the following:
using (IUnitOfWork unitOfWork = new DBContext())
{
GenericRepository<Operator> operatorRepos = new GenericRepository<Operator>(unitOfWork);
{
try
{
var oper = operatorRepos.Find(o => o.OperatorID == operatorID).Include(o => o.cmn_Address).Single();
return oper;
}
catch (InvalidOperationException exc)
{
//handle exception
}
}
}
The Find method for my repository:
public IQueryable<T> Find(Func<T, bool> predicate)
{
return _objectSet.Where<T>(predicate).AsQueryable();
}
On the page, I try to access the cmn_address Navigation property of the Operator and I get the following error:
The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.
I realize that this is caused by the using statement to dispose of the context, but I thought the Include method will eager load the cmn_Address object. I don't understand why this doesn't work as I expected.
You are using Func<> instead of Expression<Func<>> in your where condition. That makes it Linq-to-objects. This change is permanent. Calling AsQueryable doesn't make it Linq-to-entities again.
Let's say I have the following interceptor in a SEAM app:
public class MyInterceptor {
#In
private Monitor myMonitor;
#AroundInvoke
public Object aroundInvoke(InvocationContext ctx) throws Exception {
try {
myMonitor.a();
return ctx.proceed();
}
finally {
myMonitor.b();
}
}
}
myMonitor.a() works (so Monitor is correctly injected), myMonitor.b() fails because Monitor is already null. Seam Doc says: "Injected values are disinjected (i.e., set to null) immediately after method completion and outjection."
Is that what is happening? Can I do something to tell SEAM to "not yet" "disinject" the component? I can of course also do something like XContext.get(..), but I'm wondering whether this is a bug or a mistake from my side. thanks!
Try this one instead
Object response = null;
try {
myMonitor.a();
response = ctx.proceed();
} finally {
myMonitor.b();
}
return response;
regards,
Avoid using injection.
Try working around this problem. I see you have some sort of monitoring going on. Look at this interceptor that captures the amount of time a method is executed in Seam components. Try modifying your code to match that.
It works great!
Here is the link
Seam is working as advertised.
You could just ignore the disinjection:
public class MyInterceptor {
private Monitor myMonitor;
#In
private void setMonitor(Monitor aMonitor) {
if (aMonitor != null) {
myMonitor = aMonitor;
}
}
#AroundInvoke
public Object aroundInvoke(InvocationContext ctx) throws Exception {
try {
myMonitor.a();
return ctx.proceed();
}
finally {
myMonitor.b();
myMonitor = null; //perform disinjection yourself
}
}
}
The caveat here is that Seam is disinjecting the reference for a reason. Seam wants to control the lifecycle and identity of "myMonitor" and by keeping a reference to it, you are not abiding by your contract with Seam. This could lead to unexpected behavior.
For instance, if myMonitor were for some reason in the Stateless scope, Seam might destroy it before ctx.proceed() returns, leaving you with a reference to a broken proxy. Best advice is to know the scope and lifecycle of what you are retaining since you are "living on the edge."
I'm a little bit stuck with a asp.net project that i'm doing! I have got a class that is called from the code behind and many of its function have no return type ie, being void. How does one do exception handling then??? Also, if the function within the class does have a return type of, for instance, a dataset how would one then return an exception or indicate that an exception had occured? I have attached the following code from my class which is referenced from the code behind.
public void fnRecord(string []varList, string fnName)
{
try
{
String x;
StringBuilder SQLParameters = new StringBuilder();
SQLParameters.AppendLine("SELECT #{Function}(");
{
SQLParameters.Replace("#{Function}", fnName);
}
for (int i = 0; i < varList.Length; i++)
{
x = varList[i].ToString();
SQLParameters.Append("'" + x + "',");
}
SQLParameters.Remove((SQLParameters.Length - 1), 1);
SQLParameters.Append(")");
string SQLCMD = SQLParameters.ToString();
conn.Open();
NpgsqlCommand command = new NpgsqlCommand(SQLCMD, conn);
Object result = command.ExecuteScalar();
}
catch (NpgsqlException ne)
{
//return ne;
}
catch (Exception x)
{
//error code
}
finally
{
conn.Close();
}
}
Any help would be appreciated!
Thanks
Only catch the exceptions where you intend to handle them properly. If you want to reflect the errors in the UI, catch them at the UI. If you want to handle them and try to deal with the issue in the business logic, then catch them and handle them at that point.
By the way, your code is susceptable to SQL injection attacks. Best go learn something about parameterised queries.
You don't return exceptions. You throw them. That's the point of exceptions - you don't want exception handling cluttering your method signatures!
In your catch clauses, you don't actually do anything to handle the exceptions. Then you should not catch them at all, just let them bubble up to your code-behind, and catch them there - put a try-catch round the method call.
Alternatively, catch your SQL exceptions in your method, then throw a new exception with some sensible message, adding the SqlExceptions as the inner exception, like this
catch (NpgsqlException ne)
{
throw new Exception("Your explanatory message here", ne);
}
finally
{
...
}
Cool thanks for the answers... working with the obout library so have to try and work out their exception handling functions too.