1

I am getting the error

Function 'Login' doesn't return a value on all code paths. Are you missing a 'Return' statement?

which I understand to a certain extent from viewing various questions on Stack Overflow. My confusion is that I have a return value for all code paths - don't I?

Public Function Login(Username As String, Password As Integer) As Integer

    Dim tableAdapter As New AcquisitionPortalDataSetTableAdapters.ITVF_LoginLogoutTableAdapter
    Dim dt As DataTable = tableAdapter.GetData(Username, Convert.ToInt32(Password))

    Try
        If dt IsNot Nothing AndAlso dt.Rows.Count > 0 Then
            For Each dr In dt.Rows
                If dr("LAN").ToString = Username AndAlso Convert.ToInt32(dr("Code")) = Password Then
                    GlobalVariables.iUserType = Convert.ToInt32(dr("Code"))
                    GlobalVariables.iUserID = Convert.ToInt32(dr("ID"))
                    Return 1
                Else
                    Return 0
                End If
            Next
        Else
            Return 0
        End If
    Catch
        Return 0
    End Try

End Function

I've gone over this many times and each statement can be evaluated as far as I can tell. Can anyone advise otherwise, ideally with a brief explanation if possible, so I understand for the future?

2
  • 1
    Put Login = 0 at the very first line in function. Commented Dec 19, 2014 at 11:13
  • That's good but I am also waiting for a logical explanation. Commented Dec 19, 2014 at 11:21

2 Answers 2

5

It is because the compiler doesn't know that you are checking if the table has rows and so assumes that the For Each loop may not be entered into by your code path. In fact there isn't really any need to check the number of rows first because the For Each loop will have zero iterations if there are no rows in it anyway.

To fix the warning you need to cover that eventuality explicitly:

Public Function Login(Username As String, Password As Integer) As Integer

    Dim tableAdapter As New AcquisitionPortalDataSetTableAdapters.ITVF_LoginLogoutTableAdapter
    Dim dt As DataTable = tableAdapter.GetData(Username, Convert.ToInt32(Password))

    Try
        If dt IsNot Nothing AndAlso dt.Rows.Count > 0 Then
            For Each dr In dt.Rows
                If dr("LAN").ToString = Username AndAlso Convert.ToInt32(dr("Code")) = Password Then
                    GlobalVariables.iUserType = Convert.ToInt32(dr("Code"))
                    GlobalVariables.iUserID = Convert.ToInt32(dr("ID"))
                    Return 1
                Else
                    Return 0
                End If
            Next
            Return 0 'return here when there are no rows in the datatable
        Else
            Return 0
        End If
    Catch
        Return 0
    End Try

End Function

Having said that you function can be made simpler (and quicker) if your usernames are unique because if you find the usernme you don't have to check for any more:

Public Function Login(Username As String, Password As Integer) As Integer

    Dim tableAdapter As New AcquisitionPortalDataSetTableAdapters.ITVF_LoginLogoutTableAdapter
    Dim dt As DataTable = tableAdapter.GetData(Username, Convert.ToInt32(Password))
    If dt Is Nothing Then Return 0

    For Each dr As DataRow In dt.Rows
        If dr.Field(Of String)("LAN") = Username Then
            'we found the username now check the password
            Return If(dr.Field(Of Int32)("Code") = Password, 1, 0)
        End If
    Next

    'we didn't find a matching username
    Return 0

End Function
Sign up to request clarification or add additional context in comments.

Comments

-1

Can't you just put one return statement after the End Try? And make a variable at the start of the function which holds the result? At the end of the function, just return that result.

I'm not familiar with VB.NET, but that should do the trick.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.