Python Requests Exception Safety - exception

A day with spotty internet has revealed numerous bugs in my python application. I'm using requests to get information from a webservice. I've already written code that checks if the return status is 200 or else but I didn't check for connection problems.
Here is my question:
Should I wrap every GET/PUT/POST call in a try/except block?
My goal is that the user have a nice experience and not have to restart the program.
Bonus points for showing me a lightweight way to wrap all my existing calls.

Yes. It is always good to implement exception handling. It does not only help to avoid unexpected exit of script but can also help to log errors and info notification. When using Python requests I prefer to catch exceptions like this:
try:
res = requests.get(adress,timeout=30)
except requests.ConnectionError as e:
print("OOPS!! Connection Error. Make sure you are connected to Internet. Technical Details given below.\n")
print(str(e))
except requests.Timeout as e:
print("OOPS!! Timeout Error")
print(str(e))
except requests.RequestException as e:
print("OOPS!! General Error")
print(str(e))
except KeyboardInterrupt:
print("Someone closed the program")

Yes you should:
try:
r = requests.get(http://www.example.com)
if r.status_code == 200:
print(r.url, " Status Code: ", r.status_code)
except requests.ConnectionError:
print(r.url, " Failed to connect")

Related

Python capturing "HTTP status code" exception messages

I am having problems error handling code when deleting a file from box.com using Box API. The code establishes a connection to Box.com via JSON.
client.file(file_id=99999999999).delete()
When I run the command, the Box APIs uses HTTP status codes to communicate if a request has been successfully processed or not. This is what I see in PyCharm:
Error output
How do I use this error response (the red text in the bottom of the screen to handle errors so I can do something like this:
try:
client.file(file_id=xxxxxxxxxx).delete()
except 404:
print('error 404 occurred')
except 405:
print('error 405 occurred')
Thanks
#xaleel
I have tried this:
config = JWTAuth.from_settings_file(JSONFile)
client = Client(config)
try:
client.file(file_id=99999999999).delete()
except BoxAPIException as e:
print(e.status)
The error returned is:
Traceback (most recent call last):
File "C:\Temp\Box\Test\Test.py", line 20, in
except BoxAPIException as e:
NameError: name 'BoxAPIException' is not defined. Did you mean: 'BaseException'?
I have also tried "BoxException". Is this case sensitive? where can I look to see the correct possible name to use? Sorry I am not a programmer and really new to Python. I just set myself this challenge to learn!

Citrus fails to find reply channel when receiving & sending messages in parallel

I'm using the Citrus framework to test Camel routes. I'm sending a request to the Camel-based application which in turn sends multiple requests in parallel to a SOAP server.
I'm trying to mock the SOAP server with Citrus using the parallel container. I use selectors to trigger the correct receive and send actions similar to the following example (the real code is a bit more complicated):
parallel().actions(
sequential().actions(
soap().server("soapService")
.receive()
.selector("xpath:local-name(/*)='exampleRequest1' AND xpath://ns1:id/text()='123'")
.payload(new ClassPathResource("data/123/exampleRequest1.xml")),
echo("Received exampleRequest1"),
soap().server("soapService")
.send()
.payload(new ClassPathResource("data/123/exampleResponse1.xml")),
echo("Sent exampleResponse1"),
),
sequential().actions(
soap().server("soapService")
.receive()
.selector("xpath:local-name(/*)='exampleRequest2' AND xpath://ns1:id/text()='456'")
.payload(new ClassPathResource("data/456/exampleRequest2.xml")),
echo("Received exampleRequest2"),
soap().server("soapService")
.send()
.payload(new ClassPathResource("data/456/exampleResponse2.xml")),
echo("Sent exampleResponse2"),
),
...
)
Citrus does indeed receive the messages but it cannot reply. The error message of each parallel thread is:
13:35:36.121 [Thread-22] ERROR com.consol.citrus.container.Parallel - Parallel test action raised error
java.lang.IllegalArgumentException: Failed to find reply channel for message correlation key: citrus_message_id = 'c37eb703-4fb3-4c34-98f8-9cf8ee0414a1'
at org.springframework.util.Assert.notNull(Assert.java:198)
at com.consol.citrus.channel.ChannelSyncConsumer.send(ChannelSyncConsumer.java:73)
at com.consol.citrus.actions.SendMessageAction.doExecute(SendMessageAction.java:125)
…
Important: The citrus_message_id that each thread is looking for is always the same but should be different. So if one of the send actions actually succeeds, it's usually sending with the wrong reply channel.
What could be the problem here? Is this a bug or am I missing something?
Thank you very much!
The parallel container causes the problems here. But you can safely remove the parallel container when using selectors in receive actions. It should work fine for you once you have removed the parallels

How to handle "Unexpected EOF at target" error from API calls?

I'm creating a Forge application which needs to get version information from a BIM 360 hub. Sometimes it works, but sometimes (usually after the code has already been run once this session) I get the following error:
Exception thrown: 'Autodesk.Forge.Client.ApiException' in mscorlib.dll
Additional information: Error calling GetItem: {
"fault":{
"faultstring":"Unexpected EOF at target",
"detail": {
"errorcode":"messaging.adaptors.http.flow.UnexpectedEOFAtTarget"
}
}
}
The above error will be thrown from a call to an api, such as one of these:
dynamic item = await itemApi.GetItemAsync(projectId, itemId);
dynamic folder = await folderApi.GetFolderAsync(projectId, folderId);
var folders = await projectApi.GetProjectTopFoldersAsync(hubId, projectId);
Where the apis are initialized as follows:
ItemsApi itemApi = new ItemsApi();
itemApi.Configuration.AccessToken = Credentials.TokenInternal;
The Ids (such as 'projectId', 'itemId', etc.) don't seem to be any different when this error is thrown and when it isn't, so I'm not sure what is causing the error.
I based my application on the .Net version of this tutorial: http://learnforge.autodesk.io/#/datamanagement/hubs/net
But I adapted it so I can retrieve multiple nodes asynchronously (for example, all of the nodes a user has access to) without changing the jstree. I did this to allow extracting information in the background without disrupting the user's workflow. The main change I made was to add another Route on the server side that calls "GetTreeNodeAsync" (from the tutorial) asynchronously on the root of the tree and then calls it on each of the returned children, then each of their children, and so on. The function waits until all of the nodes are processed using Task.WhenAll, then returns data from each of the nodes to the client;
This means that there could be many api calls running asynchronously, and there might be duplicate api calls if a node was already opened in the jstree and then it's information is requested for the background extraction, or if the background extraction happens more than once. This seems to be when the error is most likely to happen.
I was wondering if anyone else has encountered this error, and if you know what I can do to avoid it, or how to recover when it is caught. Currently, after this error occurs, it seems that every other api call will throw this error as well, and the only way I've found to fix it is to rerun the code (I use Visual Studio so I just rerun the server and client, and my browser launches automatically)
Those are sporadic errors from our apigee router due to latency issues in the authorization process that we are currently looking into internally.
When they occur please cease all your upcoming requests, wait for a few minutes and retry again. Take a look at stuff like this or this to help you out.
And our existing reports calling out similar errors seem to point to concurrency as one of the factors leading up to the issue so you might also want to limit your concurrent requests and see if that mitigate the issue.

Model derivative translate job giving status code 409 (CONFLICT)

How to fix status code 409 for translate job.
There are two types of problems I am facing.
1. Sometimes API returns error status code 409(conflict)
2. Sometimes it continuously gives in progress status and never completes or fails even.
Once any of the above error occurs, any subsequent job requests starts failing with error code 409.
We are trying node js API for translating job using following code.
let translateResult = derivativesAPI.translate(job, { 'xAdsForce': true }, forgeSvc.requestOAuth2TwoLeggedOBJ(), accessToken);
First try to delete manifest for the stuck/pending request file,
If that doesn't works , last option is to delete the bucket with pending/stuck translation request and then try again.
As per documentation, the 409 means:
The request conflicts with a previous request that is still in progress
As you mentioned a previous request failed, but is pending on our system and causes this conflict. Is that happening consistently with a file? Or random? When it fails (or hangs), what's the manifest? Finally, can you share a problematic URN?
EDIT: the file is working now and we'll keep investigating this.

Why doesn't try/catch work in Matlab when the Image Acquisition Toolbox drops frames?

I am using Matlab's Image Acquisition Toolbox to acquire high-speed video over gigabit Ethernet. I'm having some trouble with frame-dropping, but that's not what this question is about. What I really want to do is tell Matlab to continue running the script even after encountering the frame-dropping error.
I used a try/catch statement for this purpose but it just doesn't work. Here is my code, sparing some of the details relating to setting up the camera and using the data:
%% setting up camera
while(1)
% continue acquiring data forever
while(vidObj.FramesAvailable < vidObj.FramesPerTrigger)
% wait until we're ready to get the data
try
pause(.1)
catch exception
disp "i got an error"
end
end
% get the data
[img, t] = getdata(vidObj);
%% do something with the data
%% ...
end
What happens is that, every once in a while, some frames are dropped and the toolbox raises an error. This happens inside the try block, but Matlab raises an exception anyway! The output looks something like:
Error event occurred at 21:08:20 for video input object: Mono8-gige-1.
gige: Block/frame 1231 is being dropped beecause a lost packet is unable to be resent....
Error in script_name (line 82)
pause(.1)
You can see that the error occurs while we're waiting to collect data (the "pause" statement), which is inside the try block, and yet the exception is not caught correctly because my debugging message doesn't print and the program grinds to a halt.
How can I get Matlab to observe the try/catch structure and continue after this error happens?
I figured it out. The error message is not a true error, but more of a warning. Execution does not stop. However, vidObj stops collecting frames and my code keeps looping forever, waiting for enough frames to be collected.
You can insert a check for this condition like so:
% wait until enough frames are available
while(vidObj.FramesAvailable < vidObj.FramesPerTrigger)
pause(.1)
if strcmp(vidObj.Running, 'off')
% It has stopped running, probably because frames were dropped
start(vidObj)
end
end
Now, upon frame dropping, the object will be restarted and acquistion continues. Obviously the dropped frames cannot be recovered so there will be a gap in the video.