GoogleCloudFunctionsのデプロイでハマった('ascii' codec can't encode character u'\u281b' in position 58 が出る)


概要

  • GCPのCloudFunctionsをローカルからデプロイしようとしたらうまくいかなかった
  • 試行錯誤の末にうまくいくようになったので、検証経緯と解決策をメモる
  • 似たようなエラーにハマった方への助けになれば幸いです

エラー内容

[usr_id@PC_NAME] ~/Documents/project/function_name
% gcloud functions deploy function-name --region asia-northeast1 --runtime python37 --trigger-topic topic-name         # デプロイコマンド
Deploying function (may take a while - up to 2 minutes)...failed.                                                                                                                                                                                                         
ERROR: gcloud crashed (UnicodeEncodeError): 'ascii' codec can't encode character u'\u281b' in position 58: ordinal not in range(128)
If you would like to report this issue, please run the following command:
  gcloud feedback
To check gcloud for common problems, please run the following command:
  gcloud info --run-diagnostics
[usr_id@PC_NAME] ~/Documents/project/function_name
% gcloud info --run-diagnostics         # エラー詳細
Network diagnostic detects and fixes local network connection issues.
Exception in thread Thread-1:                                                                                                                                                                                                                                             
Traceback (most recent call last):
  File "/Users/usr_id/.pyenv/versions/2.7.0/lib/python2.7/threading.py", line 530, in __bootstrap_inner
    self.run()
  File "/Users/usr_id/.pyenv/versions/2.7.0/lib/python2.7/threading.py", line 483, in run
    self.__target(*self.__args, **self.__kwargs)
  File "/Users/usr_id/google-cloud-sdk/lib/googlecloudsdk/core/console/progress_tracker.py", line 164, in Ticker
    if self.Tick():
  File "/Users/usr_id/google-cloud-sdk/lib/googlecloudsdk/core/console/progress_tracker.py", line 235, in Tick
    self._Print(self._GetSuffix())
  File "/Users/usr_id/google-cloud-sdk/lib/googlecloudsdk/core/console/progress_tracker.py", line 261, in _Print
    self._console_output.UpdateConsole()
  File "/Users/usr_id/google-cloud-sdk/lib/googlecloudsdk/core/console/multiline.py", line 154, in UpdateConsole
    self._UpdateConsole()
  File "/Users/usr_id/google-cloud-sdk/lib/googlecloudsdk/core/console/multiline.py", line 168, in _UpdateConsole
    self._messages[self._last_print_index].Print()
  File "/Users/usr_id/google-cloud-sdk/lib/googlecloudsdk/core/console/multiline.py", line 281, in Print
    self._WriteLine(line)
  File "/Users/usr_id/google-cloud-sdk/lib/googlecloudsdk/core/console/multiline.py", line 331, in _WriteLine
    self._stream.write(self._level * INDENTATION_WIDTH * ' ' + line)
UnicodeEncodeError: 'ascii' codec can't encode character u'\u281b' in position 30: ordinal not in range(128)
Checking network connection...done.                                                                                                                                                                                                                                       
Reachability Check passed.
Network diagnostic passed (1/1 checks passed).
Property diagnostic detects issues that may be caused by properties.
Checking hidden properties...done.                                                                                                                                                                                                                                        
Hidden Property Check passed.
Property diagnostic passed (1/1 checks passed).
  • デプロイしたらよくわからないエラーが出る
gcloud crashed (UnicodeEncodeError): 'ascii' codec can't encode character u'\u281b' in position 58: ordinal not in range(128)
  • ログを見るとデプロイまではうまくいって、ターミナルに結果を返すところで失敗しているように見える
  • コンソールを見ると、デプロイは成功している
  • おそらくターミナルに結果を返そうとしているところでエラーが出ている

設定内容

  • SDKで利用しているPython
    • pyenvで入れたpython2.7
[usr_id@PC_NAME] ~/Documents/project/function-name
% echo $CLOUDSDK_PYTHON
/Users/usr_id/.pyenv/versions/2.7.0/bin/python

対応その1

デフォルトエンコード変更前

% $CLOUDSDK_PYTHON
Python 2.7 (r27:82500, Nov  1 2019, 14:21:44)
[GCC 4.2.1 Compatible Apple LLVM 10.0.1 (clang-1001.0.46.4)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.getdefaultencoding()
'shift-jis'
>>>

デフォルトエンコードを変更してみる

[usr_id@PC_NAME] ~/.pyenv/versions/2.7.0/lib/python2.7/site-packages
% pwd
/Users/usr_id/.pyenv/versions/2.7.0/lib/python2.7/site-packages
[usr_id@PC_NAME] ~/.pyenv/versions/2.7.0/lib/python2.7/site-packages
% cat sitecustomize.py
import sys
sys.setdefaultencoding('utf-8')
[usr_id@PC_NAME] ~/.pyenv/versions/2.7.0/lib/python2.7/site-packages
% $CLOUDSDK_PYTHON
Python 2.7 (r27:82500, Nov  1 2019, 14:21:44)
[GCC 4.2.1 Compatible Apple LLVM 10.0.1 (clang-1001.0.46.4)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.getdefaultencoding()
'utf-8'
>>>
  • ダメだった
  • そもそもデフォルトエンコードが shift-jis になっていて、エラー内容の 'ascii' codec can't encode に合わない
  • もしかして $CLOUDSDK_PYTHON でpyenvで入れたpythonを指定しているけど、デプロイで実際に使われているpythonは違うものが使われている・・・?

対応その2

  • MacデフォルトのPythonでデフォルトエンコードを変更してみる → これで解決!

変更してみる

[usr_id@PC_NAME] /Library/Python/2.7/site-packages
% echo $CLOUDSDK_PYTHON
/usr/bin/python2.7
[usr_id@PC_NAME] /Library/Python/2.7/site-packages
% pwd
/Library/Python/2.7/site-packages
[usr_id@PC_NAME] /Library/Python/2.7/site-packages
% $CLOUDSDK_PYTHON
Python 2.7.16 (default, Oct 16 2019, 00:34:56)
[GCC 4.2.1 Compatible Apple LLVM 10.0.1 (clang-1001.0.37.14)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.getdefaultencoding()
'utf-8'
>>>
  • これで解決した!
[usr_id@PC_NAME] ~/Documents/project/function-name
% gcloud functions deploy function-name --region asia-northeast1 --runtime python37 --trigger-topic topicname
Deploying function (may take a while - up to 2 minutes)...done.                                                                                                                                       
availableMemoryMb: 256
entryPoint: function-name
eventTrigger:
  eventType: google.pubsub.topic.publish
  failurePolicy: {}
  resource: projects/project-name/topics/topicname
  service: pubsub.googleapis.com
ingressSettings: ALLOW_ALL
labels:
  deployment-tool: cli-gcloud
name: projects/project-name/locations/asia-northeast1/functions/function-name
runtime: python37
serviceAccountEmail: [email protected]
sourceUploadUrl: hogehoge
status: ACTIVE
timeout: 60s
updateTime: '2020-02-06T02:15:16Z'
versionId: '19'

原因(想像)

  • cli実行後のインジケーターのところで出力している記号がasciiだと表示できないっぽい
    • u'\u281b'→ ⠛ この記号だった
    • ↓のくるくるしてるとこ
  • なのでデプロイだけ成功して、コマンド実行したターミナル表示のところだけ失敗したっぽい
  • $CLOUDSDK_PYTHON で指定してるからそっちのpythonが利用されるかと思いきや、Macデフォルトのほうが使用されてたりする。PATHも通してたはずなんだが・・・・
    • pyenvに頼りすぎるのは良くないのかもしれない

備考

  • gcloudコマンドのバージョンとかメモるの忘れた(Qiita記事書いてる環境とハマった環境が別なため)ので、あとで覚えてたら追記します