Igor's Blog

I've been implementing user file uploads for an App Engine application when I hit a problem on my local development server. Even on successful uploads from the client side, I would always get a 500 error on the server side, like so:
ERROR 2017-06-01 23:30:46,394 module.py:899] Request to '/_ah/upload/ahNkZXZ-dHJhdmVsbWljcm9ibG9nciILEhVfX0Jsb2JVcGxvYWRTZXNzaW9uX18YgICAgIDIowoM' failed

The code to create the upload URL looked like this:
$options = [
'gs_bucket_name' => '#default#',
'url_expiry_time_seconds' => 86400
$url = CloudStorageTools::createUploadUrl('/admin/api/assets/upload', $options);

So that seemed to be correct, but as I later found out it wasn't. To track down the problem, I had to enable debug output for the dev server itself. This is done by passing --dev_appserver_log_level=debug when running the dev_appserver.py script. For me the whole command line looked like this:
 Dev Server
dev_appserver.py --port=8080 -A=travelmicroblog --runtime=php55 --log_level=debug --dev_appserver_log_level=debug app.yaml

Now I was getting more detailed error messages, including a stack trace, like so:
ERROR 2017-06-01 23:34:32,927 module.py:897] Request to '/_ah/upload/ahNkZXZ-dHJhdmVsbWljcm9ibG9nciILEhVfX0Jsb2JVcGxvYWRTZXNzaW9uX18YgICAgIDonQoM' failed
Traceback (most recent call last):
File "/Volumes/Data HD/Personal/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/module.py", line 890, in _handle_request
ret = handler.handle(match, environ, wrapped_start_response)
File "/Volumes/Data HD/Personal/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/wsgi_handler.py", line 60, in handle
return self._wsgi_app(environ, start_response)
File "/Volumes/Data HD/Personal/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/blob_upload.py", line 598, in __call__
File "/Volumes/Data HD/Personal/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/blob_upload.py", line 559, in store_blob_and_transform_request
File "/Volumes/Data HD/Personal/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/blob_upload.py", line 452, in store_and_build_forward_message
content_type, gs_filename, blob_file, filename)
File "/Volumes/Data HD/Personal/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/blob_upload.py", line 265, in store_gs_file
{'content-type': content_type})
File "/Volumes/Data HD/Personal/google-cloud-sdk/platform/google_appengine/google/appengine/api/datastore.py", line 2777, in inner_wrapper
return func(*args, **kwds)
File "/Volumes/Data HD/Personal/google-cloud-sdk/platform/google_appengine/google/appengine/ext/cloudstorage/cloudstorage_stub.py", line 161, in post_start_creation
File "/Volumes/Data HD/Personal/google-cloud-sdk/platform/google_appengine/google/appengine/ext/cloudstorage/common.py", line 286, in validate_file_path
'but got %s' % path)
ValueError: Path should have format /bucket/filename but got /#default#/fake-9RB3va819BclBVNwwjrE7g==

The final message in the output was key here...
ValueError: Path should have format /bucket/filename but got /#default#/fake-9RB3va819BclBVNwwjrE7g==

After some experimenting and re-reading the documentation I realised that the default bucket name '#default#'can't be used in this case. Even though much of the PHP runtime does support this shorthand expression, when working with the CloudStorageTools class, you have to provide the actual bucket name.

I still wanted to use the default bucket, so used the CloudStorageTools::getDefaultGoogleStorageBucketName() function to retrieve it. My $options array now looked like this:
$options = [
'gs_bucket_name' => CloudStorageTools::getDefaultGoogleStorageBucketName(),
'url_expiry_time_seconds' => 86400

Once I made that change, all of my uploads started working!


comments powered by Disqus
Other posts you may like...
Programming, DIY, Games, Hacks, and Tech

Recent Blog Posts

A guide for plotting your hard drive for Burstcoin mining on a Mac using mjminer

Replacing a broken hard drive in a Samsung Story Station

Fix Java applications slow start and net connection times on macOS sierra

Pierre Cardin Leather Computer Bag (PC2278)

How to stop SSH remote host disconnecting your session

Using PayPal PHP SDK on Google App Engine

Use the Touch Bar to lock your Mac with a single button press

Multi module builds with Maven 3.5 and the parent-child pom version management

Google App Engine local dev server DataStore becoming corrupted after a bad GQL statement is run

Unboxing my new 2017 2.9Ghz 15" MacBook Pro

Recent Galleries

Monument Valley 2 is released and does not disappoint

Space Food - Chocolate Ice Cream with Chocolate Chips

Legeod Star Wars AT-DP kit

DIY spare parts computer build with a RAIDMAX Anura case

Fake 'Lepin' brand Lego packaging

Hardwood garden bench with clear resin void filler

Fixing a 3D printer extruder that stopped heating up

Easily increase disk space in a Lenovo Ideapad 100S 14" laptop with an M.2 SSD

Making a multi-piece 3D printed solder spool holder stand

DIY indoor apartment grow light wiring

My Other Web Sites

Igor and Elise's Travels
Riverside Expressway Cam
300 George St Blogumentary

My Online Tools

UUID to OID Converter
Guru JSON-RPC Tester
Extrudifier Object Designer
Travel ┬ÁBlog

Blogs and Friends

Matt Moores Blog
Georgi's FlatPress Guide
Perplexing Permutations
The Security Sleuth
Ilia Rogatchevski
Travelling Fairy

Blog Activity

Blog Activity
Your call, follow me if you want to read more great posts like this one!
Don't show this again