This project is read-only.
1
Vote

Exceptional 0.7.3 fails if inside try..catch block

description

When there are multiple exceptions that can be caught, Exceptional fails after creating the try..catch block for the first exception. This is true whether Exceptional has created the try..catch block itself or is just in an existing try..catch block.

Error reported: Cannot perform this action, most likely because of errors in the source code

See attachment

file attachments

comments

sngbrdb wrote Sep 17, 2015 at 3:59 PM

Version 0.7.4 was just released a couple of weeks ago, so the code here is lagging. However, the problem still exists in the most recent version.

rsuter wrote Sep 17, 2015 at 5:01 PM

0.7.4 was just for supporting the latest resharper version..

sngbrdb wrote Sep 25, 2015 at 5:45 PM

I downloaded the source and resolved the issue... the problem was that the create-try-catch and add-catch-clause code were two separate code paths, and the code to add a catch clause passed null as an IBlock parameter.

There were a couple of different ways it could have been resolved, but after inspecting code usage, I resolved it in CodeElementFactory.CreateSpecificCatchClause(), starting at line 77 (the #if R8 pre-compiler directive).

Old code:
#if R8
                var declaredTypeUsageNode = _factory.CreateDeclaredTypeUsageNode(exceptionType);
#else
                //  Failed on this line when catchBody was null
                var declaredTypeUsageNode = _factory.CreateDeclaredTypeUsageNode(exceptionType, catchBody);
#endif
                exceptionDeclaration.SetDeclaredTypeUsage(declaredTypeUsageNode);
            }

            if (catchBody != null)
            {
                var catchWithBody = catchClause as ICatchClause;
                catchWithBody.SetBody(catchBody);
            }
New Code:
#if R8
                var declaredTypeUsage = _factory.CreateDeclaredTypeUsageNode(exceptionType);
#else
                if (catchBody == null) {
                    catchBody = _factory.CreateBlock("{$1    //  To-Do:  Handle the $0 $1}", exceptionType.GetClrName().ShortName, Environment.NewLine);
                }
                var declaredTypeUsageNode = _factory.CreateDeclaredTypeUsageNode(exceptionType, catchBody);

#endif
                exceptionDeclaration.SetDeclaredTypeUsage(declaredTypeUsageNode);
            }
            
            catchClause.SetBody(catchBody);
I thought it was strange to have to create a try..catch statement just to grab a dummy catch clause, but I dug through the Resharper documentation and model, and I can't find a good way to just create the catch clause directly – assuming that's why you coded it that way. Looks like the issue is there's no way to know what type of ISpecificCatchClause to instantiate... was hoping for a call into the Resharper API to create one, from the current file or node, maybe, but there's probably reasons that won't work.

Looking at coding an "add all" QuickFix... having that would rocket this from the best Resharper Plugin available to... whatever is 10x higher than that. Thanks for your hard work on this plugin.

rsuter wrote Sep 25, 2015 at 6:37 PM

Is this fine for you?
public ISpecificCatchClause CreateSpecificCatchClause(IDeclaredType exceptionType, IBlock catchBody, string variableName)
{
    var tryStatement = _factory.CreateStatement("try {} catch(Exception $0) {}", variableName) as ITryStatement;
    if (tryStatement == null) 
        return null;

    var catchClause = tryStatement.Catches[0] as ISpecificCatchClause;
    if (catchClause == null)
        return null;

    if (catchBody == null)
    {
        catchBody = _factory.CreateBlock("{$1    // TODO: Handle the $0 $1}",
            exceptionType.GetClrName().ShortName, Environment.NewLine);
    }

    if (exceptionType != null)
    {
        var exceptionDeclaration = catchClause.ExceptionDeclaration;
        if (exceptionDeclaration == null) 
            return null;

#if R8
        var declaredTypeUsageNode = _factory.CreateDeclaredTypeUsageNode(exceptionType);
#else
        var declaredTypeUsageNode = _factory.CreateDeclaredTypeUsageNode(exceptionType, catchBody);

#endif
        exceptionDeclaration.SetDeclaredTypeUsage(declaredTypeUsageNode);
    }

    catchClause.SetBody(catchBody);
    return catchClause;
}
I think I've already looked into "fix all", but I couldn't quickly find a simple solution...
Thank you

sngbrdb wrote Sep 25, 2015 at 7:53 PM

Yeah, that makes more sense... was neglecting Resharper 8 ( >.<) If you take on other developers, I'd definitely be interested in working on the project... in my opinion, it's the most useful Resharper plugin out there. I'm the lead developer of a good team, but most of them came up through the ranks learning .NET on their own... Can't seem to stem the tide of unhandled exceptions and confused users, or log files that provide no insight to what went wrong.

rsuter wrote Sep 26, 2015 at 2:37 PM

Hi, thanks, it would be nice to have help with the project. Can you contact me with skype: rico.suter?