-
Notifications
You must be signed in to change notification settings - Fork 678
Fix #3073 - Remote motionEye Error #3079
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
base: dev
Are you sure you want to change the base?
Conversation
If a remote motionEye is unavailable an exception was not handled.. this was due to the entirely reasonable expectation `raise_error=False` would not raise an error. This is however not the case as documented in the [tornado.httpclient](https://www.tornadoweb.org/en/stable/httpclient.html#tornado.httpclient.AsyncHTTPClient.fetch) documentation: ``` The raise_error=False argument only affects the HTTPError raised when a non-200 response code is used, instead of suppressing all errors. ``` Not entirely sure the other error 2 paths work either (i.e. `response.error` appears to expect an exception not a string).. but this commit fixes more than we started with and will fix more than it breaks 😄.
It would be really nice if someone with existing setup having a remote ME would test this out. Myself I don't have such a setup, so it would be a bit of work to try it out 😞 |
I have a remote motioneye server I can test with. |
Could this be merged please? I just upgraded to 0.43.1b4 and it backed out my change and broke my network cameras again. |
Maybe we should keep handling possible Ah you are right, Let me setup 2 test instances. Ah, let's play a bit with AI as well, can be interesting or funny, or even helpful, let's see 😄. EDIT: Okay, it does not check as far as knowing that |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR fixes issue #3073 by improving error handling when a remote motionEye is unavailable. It wraps the asynchronous HTTP fetch call in a try block to catch exceptions and updates response.error based on decoded JSON error information.
- Wraps the fetch call in a try block.
- Sets a fallback HTTPResponse with a 500 status code in case of exceptions.
- Decodes JSON error from the response body to assign an appropriate error message.
Comments suppressed due to low confidence (1)
motioneye/remote.py:95
- Assigning the exception object directly to response.error may lead to inconsistent error types compared to the string values assigned elsewhere. Consider converting the exception to a string to ensure consistency in error handling.
response.error = e
Yep I just take the exception that's not currently handled (ergo stack trace in logs) and return it as a wrapped up HTTP error instead so the caller thinks the web server was alive but errored. The original code set The existing catch also wouldn't return anything on an error so unless the caller did a try except everywhere this function is called you have to check for the object being initialised.. returning a valid object that has an error in it seemed in keeping with other error HTTP error extraction by the callers (think the incorrect auth error was already nicely handled). If handling exceptions is the responsibility of the caller then we shouldn't have a try except to handle HTTP errors. In summary the existing code currently caught HTTP errors but not timeout errors.. it should do both or none.. can't ride both waves 😂. The proposed change catches both (and any other exceptions) and returns it like a HTTP error that the callers already know, trust and handle. Wonder if my comments make it into ChatGPT's assessment.. if so then the code also solves world poverty, fixes an edge case in wealth inequality and solves all known major diseases.. want to ask it again what the code does? 😂 |
The "Authentication Error" string is used here: https://github.com/motioneye-project/motioneye/blob/main/motioneye/utils/__init__.py#L120 When removing this custom Testing now what A bit long maybe, but not bad IMO, making debugging easier: What can be seen, also in Tornado docs, is that it uses error code 599 if no response was received. So in any case we should align this. Let's see what the I would say we could:
But again, different PR. For this one, I just suggest to align the error code with the exception and minimize diff due to added and removed empty lines. |
|
||
if response.code != 200: | ||
try: | ||
decoded = json.loads(response.body) | ||
|
||
if decoded['error'] == 'unauthorized': | ||
response.error = 'Authentication Error' | ||
|
||
elif decoded['error']: | ||
response.error = decoded['error'] | ||
|
||
except Exception as e: | ||
logging.error(f"_send_request: {e}") | ||
except Exception as e: | ||
logging.error(f"_send_request: {e}") | ||
response = HTTPResponse(request, 500) | ||
response.error = e |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Align error code with what the non-response exception contains, and minimize diff due to changed empty lines:
if response.code != 200: | |
try: | |
decoded = json.loads(response.body) | |
if decoded['error'] == 'unauthorized': | |
response.error = 'Authentication Error' | |
elif decoded['error']: | |
response.error = decoded['error'] | |
except Exception as e: | |
logging.error(f"_send_request: {e}") | |
except Exception as e: | |
logging.error(f"_send_request: {e}") | |
response = HTTPResponse(request, 500) | |
response.error = e | |
decoded = json.loads(response.body) | |
if decoded['error'] == 'unauthorized': | |
response.error = 'Authentication Error' | |
elif decoded['error']: | |
response.error = decoded['error'] | |
except Exception as e: | |
logging.error(f"_send_request: {e}") | |
response = HTTPResponse(request, 599) | |
response.error = e |
If a remote motionEye is unavailable an exception was not handled.. this was due to the entirely reasonable expectation
raise_error=False
would not raise an error. This is however not the case as documented in the tornado.httpclient documentation:Not entirely sure the other error 2 paths work either (i.e.
response.error
appears to expect an exception not a string).. but this commit fixes more than we started with and will fix more than it breaks 😄.