Skip to content

Conversation

@frank-dong-ms-zz
Copy link
Contributor

@frank-dong-ms-zz frank-dong-ms-zz commented Oct 1, 2019

Fixes #4120

The issue is: when user use OnnxSequenceType attribute directly without specify sequence type like [OnnxSequenceType], user will hit run time exception when try to use it.

The ideal way to fix this issue is to remove the default constructor of OnnxSequenceTypeAttribute and user will get compiler error when he/she try to use [OnnxSequenceType].
But this can be a break change in Public API. After discuss with @eerhardt and @ericstj , we decide to obsolete the default constructor for now. Then we will remove the default constructor in next major release.

@frank-dong-ms-zz frank-dong-ms-zz requested a review from a team as a code owner October 1, 2019 22:26
@dnfclas
Copy link

dnfclas commented Oct 1, 2019

CLA assistant check
All CLA requirements met.

@codecov
Copy link

codecov bot commented Oct 1, 2019

Codecov Report

❗ No coverage uploaded for pull request base (master@e19369b). Click here to learn what that means.
The diff coverage is 94.44%.

@@            Coverage Diff            @@
##             master    #4272   +/-   ##
=========================================
  Coverage          ?   74.55%           
=========================================
  Files             ?      878           
  Lines             ?   154042           
  Branches          ?    16854           
=========================================
  Hits              ?   114851           
  Misses            ?    34453           
  Partials          ?     4738
Flag Coverage Δ
#Debug 74.55% <94.44%> (?)
#production 70.14% <100%> (?)
#test 89.52% <93.75%> (?)
Impacted Files Coverage Δ
...c/Microsoft.ML.OnnxTransformer/OnnxSequenceType.cs 89.74% <100%> (ø)
test/Microsoft.ML.Tests/OnnxSequenceTypeTest.cs 97.5% <93.75%> (ø)

if (_elemType == null)
{
throw new Exception("Please specify sequence type when use OnnxSequenceType Attribute.");
}
Copy link
Member

@codemzs codemzs Oct 2, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please do not use braces for single line if condition #Resolved

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually this is best practice to always use braces for if condition, in my previous team it is also suggested to always use braces for if condition to avoid further problem.

There is also some discussion online, please check out and see whether this make sense to you: https://softwareengineering.stackexchange.com/questions/16528/single-statement-if-block-braces-or-no


In reply to: 330344007 [](ancestors = 330344007)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Offline discussed with Zeeshan, this can be debatable, I will just follow the coding style in this team, not a big issue


In reply to: 330672086 [](ancestors = 330672086,330344007)

using System.Linq;
using System.IO;
using Microsoft.ML.TestFramework.Attributes;
using System;
Copy link
Member

@codemzs codemzs Oct 2, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please place "using System" at the top and sort alphabetical order as done in source files. System libraries take preference over non-system libraries like Microsoft.ML.* #Resolved

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, will do


In reply to: 330344198 [](ancestors = 330344198)

Copy link
Member

@codemzs codemzs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

if (_elemType == null)
{
throw new Exception("Please specify sequence type when use OnnxSequenceType Attribute.");
}
Copy link
Contributor

@harishsk harishsk Oct 2, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps it is better to throw ArgumentNullException here? #Resolved

Copy link
Member

@eerhardt eerhardt Oct 2, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Throwing just a plain Exception is not recommended.

https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/using-standard-exception-types

X DO NOT throw System.Exception or System.SystemException.

However, ArgumentNullException is not correct either, since there is no argument to this method.

✓ DO throw ArgumentException or one of its subtypes if bad arguments are passed to a member.

In this case, InvalidOperationException is the most correct:

✓ DO throw an InvalidOperationException if the object is in an inappropriate state. #Resolved

Copy link
Member

@eerhardt eerhardt Oct 2, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO - it the best approach would be to remove the empty constructor and verify the Type elemType in the other constructor is never null.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, very good suggestion, InvalidOperationException is the most proper one to use here


In reply to: 330652629 [](ancestors = 330652629)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I have a similar discussion with Harish about this yesterday, we agreed that remove empty constructor seems to be more ambiguous because when our customer use [OnnxSequenceType] attribute directly he/she will get error message like "method is inaccessible due to protection level". By throwing exception we can give user more specific error message. Make sense to you?


In reply to: 330653643 [](ancestors = 330653643)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to take Eric's suggestion and use InvalidOperationException here.


In reply to: 330649635 [](ancestors = 330649635)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when our customer use [OnnxSequenceType] attribute directly he/she will get error message like "method is inaccessible due to protection level"

That's a compile time error - which is exactly what we want. We want to raise the error as early as possible, so the user knows they are doing something wrong.

Also, when I get a different error message than what you are displaying:

    class Program
    {
        [My]
        private int foo;
    }

    class MyAttribute : Attribute
    {
        public MyAttribute(int required)
        { }
    }
Error	CS7036	There is no argument given that corresponds to the required formal parameter 'required' of 'MyAttribute.MyAttribute(int)'	ConsoleApp80	C:\Users\eerhardt\source\repos\ConsoleApp80\Program.cs	13	Active

Pretty obvious what to do to fix it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think Eric's suggestion is the better approach here. Please modify it as per his suggestion.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good to me, will do


In reply to: 330736190 [](ancestors = 330736190)

[OnnxFact]
public void OnnxSequenceTypeWithouSpecifySequenceTypeTest()
{
Exception ex = Assert.Throws<Exception>(() => CreatePredictorWithPronlematicOutputObj());
Copy link
Contributor

@harishsk harishsk Oct 2, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CreatePredictorWithPronlematicOutputObj [](start = 58, length = 39)

A small typo here with Problematic #Resolved

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, will do, thanks


In reply to: 330650375 [](ancestors = 330650375)

{
Exception ex = Assert.Throws<Exception>(() => CreatePredictorWithPronlematicOutputObj());
Assert.Equal("Please specify sequence type when use OnnxSequenceType Attribute.", ex.Message);
}
Copy link
Contributor

@harishsk harishsk Oct 2, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be better to assert on the type of exception rather than the specific message? #Resolved

Copy link
Contributor Author

@frank-dong-ms-zz frank-dong-ms-zz Oct 2, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, the exception type is assert in previous line Assert.Throws, after change to use InvalidOperationException, it should look like Assert.Throws(....), so we can assert both on exception type and exception message.


In reply to: 330651709 [](ancestors = 330651709)

Copy link
Contributor

@harishsk harishsk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🕐

@frank-dong-ms-zz frank-dong-ms-zz merged commit 24f1cca into dotnet:master Oct 4, 2019
@ghost ghost locked as resolved and limited conversation to collaborators Mar 20, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Using default OnnxSequenceType attribute throws meaningless exception

6 participants