Django exception handling - catching ghost error from server-side - django

I have a Django view that is responsible for providing raw data for graph rendering on server-side. When I run the app locally (I have Windows 10 on my machine), everything works fine. But when I run the app from the remote server (it's Ubuntu), I get an 500-error. This type of errors (when identical code is ok locally, but fails remotely), currently constitutes a serious issue for me in that on every such occasion it leads to very time-consuming - and seemingly unprofessional - process to identify and fix them. And my question is, what is the magic exception handling code snippet which would help me through the detailed exception message to client-side console.
To be more specific, consider the following (I deliberately provide the code as is):
Django view:
def graph_vendors_black_white(request):
try:
legal_entity_own_qs = get_sale_points(request.user.id)
list = []
data = [x.blacknwhite_agreement_count(True) for x in legal_entity_own_qs]
list.append({'name':u'В белую', 'data':data});
data = [x.blacknwhite_agreement_count(False) for x in legal_entity_own_qs]
list.append({'name':u'В чёрную', 'data':data});
data = [x.blacknwhite_agreement_count(None) for x in legal_entity_own_qs]
list.append({'name':u'Не выбрана опция', 'data':data});
legal_entity_own_list = [unicode(x.short_identifier_rus) for x in legal_entity_own_qs]
json_response = JsonResponse({'time_series':json.dumps(list, ensure_ascii=False).encode('utf8'),'categories':json.dumps(legal_entity_own_list, ensure_ascii=False).encode('utf8')})
return json_response
except:
user_msg, tech_msg = default_error_msg()
return JsonResponse(user_msg + '\n ' + tech_msg, status = 500, safe = False)
def default_error_msg():
user_msg = u'Что-то пошло не так'
exc_type, exc_obj, exc_tb = sys.exc_info()
fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
try:
console_msg = exc_obj[1]
except:
console_msg = str(exc_obj.message)
tech_msg = ('File - ' + fname + ' on line ' + str(exc_tb.tb_lineno) + '. \n' + \
'Error message - ' + console_msg + '\n' + \
'Exception type - ' + str(type(exc_obj)))
return user_msg, tech_msg
JS:
$.get('/graph_vendors_black_white/', function (response)
{
// ... some code
}).fail(function(json_result) {
$('#black_white_container').html(json_result.responseJSON)
});
When I run this locally, it's perfectly ok. From remote server, it throws 500 error and most surprisingly json_result does not contain error message. Whereas if I put something like a = 1/0, I get the error message in the container instead of graph.
To sum up, the question is, what is the generic exception handling code snippet which would transmit the detailed error message to the fail-function response parameter NO MATTER WHAT THE ERROR IS on the server-side

Related

Django: Problem with ContentFile: String content is not downloaded completely

I'm quite new to using Django. As first project I wrote a little tool to create M3U8-Playlists.
My problem is, that long playlists are not transferred completely.
This is the stripped-down code:
def create(request):
# just a dummy filelist
playlist = ["#EXTM3U"] + 5 * ["/home/pi/music/" + 5 * "äöü0123456789á/" + "xyz.mp3"]
file_to_send = ContentFile("")
for item in playlist:
file_to_send.write("{}\n".format(item.replace("/home/pi/Music", r"\\raspberry\music").replace("/", "\\")))
response = HttpResponse(file_to_send, "audio/x-mpegurl")
response["Content-Length"] = file_to_send.size
response["Content-Disposition"] = f"attachment; filename=\"playlist.m3u8\""
# print some debug info
print("lines:", len(playlist), "chars (no linebreaks)", sum([len(entry) for entry in playlist]),
"filesize:", file_to_send.size)
return response
The problem seems to lie in the non-ascii chars in playlist entries (äöüá). When there are no such characters, the file is transferred intact. I assume that these are characters that use two bytes in UTF-8, but writing strings to the ContentFile like I do is probably not correct.
Found the answer, while working on the problem description.
This works:
def create(request):
# just a dummy filelist
playlist = ["#EXTM3U"] + 5 * ["/home/pi/music/" + 5 * "äöü0123456789á/" + "xyz.mp3"]
joined_playlist = "\n".join([item.replace("/home/pi/Music", r"\\raspberry\music").replace("/", "\\") for item in playlist])
file_to_send = ContentFile(joined_playlist.encode("UTF-8"))
response = HttpResponse(file_to_send, "audio/x-mpegurl")
response["Content-Length"] = file_to_send.size
response["Content-Disposition"] = f"attachment; filename=\"playlist.m3u8\""
# print some debug info
print("lines:", len(playlist), "chars (no linebreaks)", sum([len(entry) for entry in playlist]),
"filesize:", file_to_send.size)
return response
The important difference is, that I don't write Strings to the ContentFile any longer, but a byte array, which I got through encoding the String in UTF-8.
HTH

how to get NOT crashed image file from Unity to Django?

I'm using Unity 2018.3. and try to HTTP POST Request with image from Unity to Django.
try to take a picture in Unity and then POST the image to Django server.
I want to receive in server and make it to image file.
well, when i send for image file to byte[] using EncodeToPNG() or EncodeToJPG(), the server got it but when i print it the data it was crash seems like encoding error. so it can't write to image format. (the take a picture code is working right.)
Django server result image
i saw a bunch of things about this issue so i tried to other way like use WWWform or JSON but anything couldn't works..
how to get image form Unity to Django?
All help appreciated! Thanks, all.
take a picture
void TakeSnapshot()
{
Texture2D snap = new Texture2D(frontCam.width, frontCam.height);
snap.SetPixels(frontCam.GetPixels());
snap.Apply();
_SavePath = pathForDocumentsFile("photo");
System.IO.File.WriteAllBytes(_SavePath + ".png", snap.EncodeToPNG());
bytes = snap.EncodeToPNG();
//bytes = snap.EncodeToJPG();
UnityEngine.Object.Destroy(snap);
path = _SavePath + ".png";
StartCoroutine(ServerThrows());
}
POST to server
IEnumerator ServerThrows()
{
List<IMultipartFormSection> formData = new List<IMultipartFormSection>();
formData.Add(new MultipartFormDataSection("photo", bytes, "byte[]"));
//UnityWebRequest www = UnityWebRequest.Post(url, null, bytes);
UnityWebRequest www = UnityWebRequest.Post(url, formData);
www.chunkedTransfer = false;
yield return www.SendWebRequest();
if (www.isNetworkError || www.isHttpError)
{
Debug.Log(www.error);
}
else
{
Debug.Log("Form upload complete!" + www.downloadHandler.text);
}
}
response in server
def post(self, request, format=None):
print('get the data')
print('request.POST: ', request.POST)
print('request.headers: ', request.headers)
data_test = request.POST.get('photo', '')
print('data test is : ', data_test)
print('type of data_test is : ', type(data_test))
print('length of data_test is : ', len(data_test))
print('finish to get ')
# data_test = data_test.decode('utf-8').encode('euc_kr','replace')
f = open('./test.png','wb')
f.write(data_test.encode())
f.close()
#
data = open('./test.png', 'rb')
return HttpResponse("post !")

Use user input and configfile to write to a new file

I am pretty new to coding, and I am attempting to have a user input words (zones). I want these to be put into a list that can be used to pull from based on the counter. The rest of the input is being pulled from a file and then then broken up using shlex.split. I'm then naming these linetokens and using them for my if statements and my naming. I was wondering if someone could look at the following code and let me know what I'm doing wrong. I don't receive any errors when I run it; however, nothing happens. I'm using python 2.7. *After adding the "main(sys.argv[1])", the script now runs but I am still receiving errors.
import sys
import shlex
def inputZone(zone):
zones = raw_input('Enter zones: ')
return zone
def main(argv):
count = int(0)
zones = zone.split(' ')
sys.stdout.flush
argv = sys.argv
if len(sys.argv) != 2:
configfile = open(str(sys.argv(1),'r'))
for configline in configfile:
with open('converted.txt','a') as converted:
linetokens = shlex.split(configline)
while count <= len(zones):
if(linetokens[0]=='set' and linetokens[1]=='group' and linetokens[3]==zones[count] and linetokens[5]=='add'):
groupObject=linetokens[4].replace(' ','_').replace('[','').replace(']','').strip()
groupZone=linetokens[3].strip(' ')
addressObjectName=linetokens[6].replace(' ','').replace('[','').replace(']','')
converted.write("set security zones security-zone " + groupZone + " address-book address-set " + groupObject + " address " + + addressObjectName +'\n')
count = count + 1
configfile.close()
main(sys.argv[1])
whats the error you are getting. I can notice many python errors in the program.
main(argv) argv is never used
zones = zone.split(' ') Zone is not declared by this time.
sys.stdout.flush is a function definition, you are not really calling it

Invalid argument for appscript UrlFetchApp.fetch

I'm trying to fetch data from the facebook FQL api using google appscript. Unfortunately, I keep getting the following error:
Error encountered: Invalid argument: https://graph.facebook.com/fql?q=SELECT+post_id,share_info,comment_info,like_info,created_time+FROM+stream+WHERE+post_id+IN+(SELECT+post_id+FROM+stream+WHERE+source_id='SOME_SOURCE_ID'+AND+created_time+>+1369869370+AND+created_time+<+1377645370+ORDER+BY+created_time+DESC+LIMIT+0,100)&access_token=XXXXXXXXX
If I copy/paste the url into my browser, I get a valid JSON response which makes me think that the url is valid, however, if I look at the execution transcript, it points me to the var postfetch = UrlFetchApp.fetch(...) line.
Here's my code.
var posturl = "https://graph.facebook.com/fql?q=SELECT+post_id,share_info,comment_info,like_info,created_time+FROM+stream+WHERE+post_id+IN+" +
"(SELECT+post_id+FROM+stream+WHERE+source_id='" + source + "'+AND+created_time+>+" + istartEpoch.toString() +
"+AND+created_time+<+" + iendEpoch.toString() + "+ORDER+BY+created_time+DESC+LIMIT+0,100)&access_token=" + token;
var postfetch = UrlFetchApp.fetch(posturl);
var postjson = postfetch.getContentText();
var postdata = Utilities.jsonParse(postjson);
It turns out that < and > aren't valid characters to put into a url. Changing them to %3E and %3C and now all is right with the world.

RubyMotion >> How to make a POST?

I've been checking out RestKit and the GET works
#client.get("/?amount=5", delegate:self)
Does anyone know how to make a POST and receive the result?
The docs mention that it looks something like this -
#client.post("/ask", params:#paramvar, delegate:self)
What do you encapsulate #paramvar? I have tried it as an array, hash and even nil - however, none of them have yielded any results.
Take a look at the bubble wrap library. It includes some really nice HTTP helpers.
http://bubblewrap.io/
Found an example in the RubyMotion_Cookbook.
https://github.com/IconoclastLabs/rubymotion_cookbook/tree/master/ch_8/06_sendinghttppost
class AppDelegate
def application(application, didFinishLaunchingWithOptions:launchOptions)
#window = UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds)
#window.rootViewController = RootController.new
url_string = "http://rubymotion-cookbook.herokuapp.com/post"
post_body = "bodyParam1=BodyValue1&bodyParam2=BodyValue2"
url = NSURL.URLWithString(url_string)
request = NSMutableURLRequest.requestWithURL(url)
request.setTimeoutInterval(30)
request.setHTTPMethod("POST")
request.setHTTPBody(post_body.to_s.dataUsingEncoding(NSUTF8StringEncoding))
queue = NSOperationQueue.alloc.init
NSURLConnection.sendAsynchronousRequest(request,
queue: queue,
completionHandler: lambda do |response, data, error|
if(data.length > 0 && error.nil?)
html = NSString.alloc.initWithData(data, encoding: NSUTF8StringEncoding)
p "HTML = #{html}"
elsif( data.length == 0 && error.nil? )
p "Nothing was downloaded"
elsif(!error.nil?)
p "Error: #{error}"
end
end
)
#window.makeKeyAndVisible
true
end
end
Source:
https://github.com/rubymotion/BubbleWrap
Insallation:-
in console run 'gem install bubble-wrap' or mention 'gem bubble-wrap' in Gemfile
Line to be added in 'app_delegate.rb'file(by this Bubblewrap api is available through out app):-
require 'bubble-wrap/http'
Sample code for syntax:-
BW::HTTP.get("https://api.github.com/users/mattetti", {credentials: {username: 'matt', password: 'aimonetti'}}) do |response|
p response.body.to_str # prints the response's body
end