Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add facility to recognize specific error messages. #27

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

EliRibble
Copy link

Also add the invalid user name and password message. This list should eventually grow as more errors are recognized. It prevents a client from having to either bubble up literally any text from RouterOS or have to rebuild all the different error strings themselves.

@archaron
Copy link
Collaborator

Great idea! Maybe we can avoid usage of map and can create errors directly inline?

const (
  ErrInvalidUserNameOrPassword = decodedDeviceError("invalid user name or password (6)")
  ErrConnection                = decodedDeviceError("... cannot connect ...")
)

type decodedDeviceError string
func (e decodedDeviceError) Error() string { return string(e) }

And then, instead of:

case trapSentence, fatalSentence:
		return sen.Word == fatalSentence, DeviceErrorFromSentence(sen)

we can create errors like this:

case trapSentence, fatalSentence:
  if msg, ok := sen.Map["message"]; ok {
   // custom error found
   return sen.Word == fatalSentence, processedDeviceError(msg)
  }

  return sen.Word == fatalSentence, &DeviceError{Sentence: sen}

So, we can do in client code:

if errors.Is(err, routeros.ErrInvalidUserNameOrPassword)  {
  // Auth error
}

Just as an idea.

BTW: Need to investigate, can error be like 'unable to connect to 192.168.0.1' ? If yes, this code will not work properly and we need some other solution to handle such errors.

Also, we need tests for this.

@EliRibble
Copy link
Author

Good ideas, next time I work on this project I'll try adding them and report back.

@EliRibble
Copy link
Author

EliRibble commented Oct 6, 2024

In your example, what is processedDeviceError doing? I didn't find a function with that name in the repo. Is it just a rename of my DeviceErrorFromSentence? If so, wouldn't we still need the map?

@archaron
Copy link
Collaborator

archaron commented Oct 6, 2024

Yep! It's my fault, of course it must be like:

return sen.Word == fatalSentence, decodedDeviceError(msg)

Just creates a new error based on sentece message.

As i can see, these errors needed for tests to pass:

const (
	ErrInvalidUserNameOrPassword = decodedDeviceError("invalid user name or password (6)")
	ErrIncorrectLogin            = decodedDeviceError("incorrect login")
	ErrAlreadyExists             = decodedDeviceError("failure: entry already exists")
)

And of course, we need to replace error check in test code from:

        var devErr *DeviceError
	require.Truef(t, errors.As(err, &devErr), "wait for device error: %v", err)
	require.Contains(t, []string{"cannot log in", "invalid user name or password (6)"}, devErr.fetchMessage())

to something like this:

      require.Equal(t, ErrInvalidUserNameOrPassword, err)

The initial list is quite short, incorporating just known errors of
invalid username/passwords, incorrect login, and 'entry already exists'.
This list should eventually grow as more errors are recognized.

By adding in these types we prevent a client from having to either bubble
up literally any text from RouterOS or have to rebuild all the different
error strings themselves.
@EliRibble
Copy link
Author

Thanks, I've updated the PR, including the tests. I had to make some adjustments to make it so other tests continue to pass, specifically proto_test.TestRunTrap which expects a DeviceError. Instead of just returning a decodedDeviceError I return a DeviceError-wrapped decodedDeviceError.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants