You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@stratos.apache.org by im...@apache.org on 2015/10/13 13:07:10 UTC
[47/50] stratos git commit: Generalized Errors
Generalized Errors
Signed-off-by: Imesh Gunaratne <im...@apache.org>
Project: http://git-wip-us.apache.org/repos/asf/stratos/repo
Commit: http://git-wip-us.apache.org/repos/asf/stratos/commit/b37cac82
Tree: http://git-wip-us.apache.org/repos/asf/stratos/tree/b37cac82
Diff: http://git-wip-us.apache.org/repos/asf/stratos/diff/b37cac82
Branch: refs/heads/stratos-4.1.x
Commit: b37cac82550e01d87ef9a0f33400fb6be9bb7856
Parents: fc7c3c1
Author: Milindu Sanoj Kumarage <ag...@gmail.com>
Authored: Sun Aug 16 23:42:12 2015 +0530
Committer: Imesh Gunaratne <im...@apache.org>
Committed: Tue Oct 13 16:32:49 2015 +0530
----------------------------------------------------------------------
.../src/main/python/cli/CLI.py | 197 +++++++++++--------
.../src/main/python/cli/Stratos.py | 70 +++----
.../cli/exceptions/AuthenticationError.py | 23 ---
.../python/cli/exceptions/BadResponseError.py | 24 +++
4 files changed, 177 insertions(+), 137 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/stratos/blob/b37cac82/components/org.apache.stratos.python.cli/src/main/python/cli/CLI.py
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.python.cli/src/main/python/cli/CLI.py b/components/org.apache.stratos.python.cli/src/main/python/cli/CLI.py
index bf01e54..1fa0a46 100755
--- a/components/org.apache.stratos.python.cli/src/main/python/cli/CLI.py
+++ b/components/org.apache.stratos.python.cli/src/main/python/cli/CLI.py
@@ -20,7 +20,8 @@ from rpm._rpm import te
from Utils import *
from Stratos import *
import Configs
-from cli.exceptions import AuthenticationError
+from Logging import logging
+from cli.exceptions import BadResponseError
class CLI(Cmd):
@@ -67,8 +68,9 @@ class CLI(Cmd):
rows.append([user['userName'], user['role']])
table.add_rows(rows)
table.print_table()
- except AuthenticationError as e:
- self.perror("Authentication Error")
+ except BadResponseError as e:
+ self.perror(str(e))
+ logging.error(str(e))
@options([
make_option('-u', '--username', type="str", help="Username of the user"),
@@ -95,8 +97,9 @@ class CLI(Cmd):
print("User successfully created")
else:
print("Error creating the user")
- except AuthenticationError as e:
- self.perror("Authentication Error")
+ except BadResponseError as e:
+ self.perror(str(e))
+ logging.error(str(e))
@options([
make_option('-u', '--username', type="str", help="Username of the user"),
@@ -119,8 +122,9 @@ class CLI(Cmd):
print("User successfully updated")
else:
print("Error updating the user")
- except AuthenticationError as e:
- self.perror("Authentication Error")
+ except BadResponseError as e:
+ self.perror(str(e))
+ logging.error(str(e))
@options([
make_option('-u', '--username', type="str", help="Username of the user"),
@@ -139,8 +143,9 @@ class CLI(Cmd):
print("You have successfully deleted user: "+name)
else:
print("Could not delete user: "+name)
- except AuthenticationError as e:
- self.perror("Authentication Error")
+ except BadResponseError as e:
+ self.perror(str(e))
+ logging.error(str(e))
"""
# Applications
@@ -204,8 +209,9 @@ class CLI(Cmd):
print("Application added successfully")
else:
print("Error adding application")
- except AuthenticationError as e:
- self.perror("Authentication Error")
+ except BadResponseError as e:
+ self.perror(str(e))
+ logging.error(str(e))
@options([
make_option('-u', '--username', type="str", help="Username of the user"),
@@ -223,8 +229,9 @@ class CLI(Cmd):
print("You have successfully removed application: "+application)
else:
print("Could not delete application : "+application)
- except AuthenticationError as e:
- self.perror("Authentication Error")
+ except BadResponseError as e:
+ self.perror(str(e))
+ logging.error(str(e))
@options([
@@ -245,8 +252,9 @@ class CLI(Cmd):
print("You have successfully deployed application: "+opts.application_id)
else:
print("Could not deployed application : "+opts.application_id)
- except AuthenticationError as e:
- self.perror("Authentication Error")
+ except BadResponseError as e:
+ self.perror(str(e))
+ logging.error(str(e))
"""
# Application deployment
@@ -312,8 +320,9 @@ class CLI(Cmd):
print("Application signup added successfully")
else:
print("Error creating application signup")
- except AuthenticationError as e:
- self.perror("Authentication Error")
+ except BadResponseError as e:
+ self.perror(str(e))
+ logging.error(str(e))
@options([
make_option('-u', '--username', type="str", help="Username of the user"),
@@ -331,8 +340,9 @@ class CLI(Cmd):
print("You have successfully remove signup: "+signup)
else:
print("Could not delete application signup: "+signup)
- except AuthenticationError as e:
- self.perror("Authentication Error")
+ except BadResponseError as e:
+ self.perror(str(e))
+ logging.error(str(e))
"""
@@ -403,7 +413,8 @@ class CLI(Cmd):
print("Created date: "+datetime.datetime.fromtimestamp(tenant['createdDate']/1000).strftime('%Y-%m-%d %H:%M:%S'))
print("-------------------------------------")
except requests.HTTPError as e:
- self.perror("Error")
+ self.perror(str(e))
+ logging.error(str(e))
@options([
make_option('-u', '--username', type="str", help="Username of the user"),
@@ -425,8 +436,9 @@ class CLI(Cmd):
print("Tenant added successfully : "+opts.domain_name)
else:
print("Error creating the tenant : "+opts.domain_name)
- except AuthenticationError as e:
- self.perror("Authentication Error")
+ except BadResponseError as e:
+ self.perror(str(e))
+ logging.error(str(e))
@options([
make_option('-u', '--username', type="str", help="Username of the user"),
@@ -449,8 +461,9 @@ class CLI(Cmd):
print("Tenant updated successfully : "+opts.domain_name)
else:
print("Error updating the tenant : "+opts.domain_name)
- except AuthenticationError as e:
- self.perror("Authentication Error")
+ except BadResponseError as e:
+ self.perror(str(e))
+ logging.error(str(e))
@options([
make_option('-u', '--username', type="str", help="Username of the user"),
@@ -468,8 +481,9 @@ class CLI(Cmd):
print("You have successfully activated the tenant : "+tenant_domain)
else:
print("Could not activate tenant : "+tenant_domain)
- except AuthenticationError as e:
- self.perror("Authentication Error")
+ except BadResponseError as e:
+ self.perror(str(e))
+ logging.error(str(e))
@options([
make_option('-u', '--username', type="str", help="Username of the user"),
@@ -487,8 +501,9 @@ class CLI(Cmd):
print("You have successfully deactivated the tenant : "+tenant_domain)
else:
print("Could not deactivate tenant : "+tenant_domain)
- except AuthenticationError as e:
- self.perror("Authentication Error")
+ except BadResponseError as e:
+ self.perror(str(e))
+ logging.error(str(e))
"""
# Cartridges
@@ -542,7 +557,8 @@ class CLI(Cmd):
print("Host Name: "+cartridge['host'])
print("-------------------------------------")
except requests.HTTPError as e:
- self.perror("Error")
+ self.perror(str(e))
+ logging.error(str(e))
@options([
make_option('-u', '--username', type="str", help="Username of the user"),
@@ -564,7 +580,7 @@ class CLI(Cmd):
print("Cartridge added successfully")
else:
print("Error adding Cartridge")
- except AuthenticationError as e:
+ except BadResponseError as e:
print("Authentication Error")
@options([
@@ -584,8 +600,9 @@ class CLI(Cmd):
print("Cartridge updated successfully")
else:
print("Error updating Cartridge")
- except AuthenticationError as e:
- self.perror("Authentication Error")
+ except BadResponseError as e:
+ self.perror(str(e))
+ logging.error(str(e))
@options([
make_option('-u', '--username', type="str", help="Username of the user"),
@@ -603,8 +620,9 @@ class CLI(Cmd):
print("Successfully un-deployed cartridge : "+cartridge_type)
else:
print("Could not un-deployed cartridge : "+cartridge_type)
- except AuthenticationError as e:
- self.perror("Authentication Error")
+ except BadResponseError as e:
+ self.perror(str(e))
+ logging.error(str(e))
"""
# Cartridge groups
@@ -669,8 +687,9 @@ class CLI(Cmd):
print("Cartridge group added successfully")
else:
print("Error adding Cartridge group")
- except AuthenticationError as e:
- self.perror("Authentication Error")
+ except BadResponseError as e:
+ self.perror(str(e))
+ logging.error(str(e))
@options([
make_option('-u', '--username', type="str", help="Username of the user"),
@@ -689,8 +708,9 @@ class CLI(Cmd):
print("Cartridge group updated successfully")
else:
print("Error updating Cartridge group")
- except AuthenticationError as e:
- self.perror("Authentication Error")
+ except BadResponseError as e:
+ self.perror(str(e))
+ logging.error(str(e))
@options([
make_option('-u', '--username', type="str", help="Username of the user"),
@@ -708,8 +728,9 @@ class CLI(Cmd):
print("Successfully un-deployed cartridge group : "+group_definition_name)
else:
print("Could not un-deployed cartridge group : "+group_definition_name)
- except AuthenticationError as e:
- self.perror("Authentication Error")
+ except BadResponseError as e:
+ self.perror(str(e))
+ logging.error(str(e))
"""
# Deployment Policies
@@ -773,8 +794,9 @@ class CLI(Cmd):
print("Deployment policy added successfully")
else:
print("Error creating deployment policy")
- except AuthenticationError as e:
- self.perror("Authentication Error")
+ except BadResponseError as e:
+ self.perror(str(e))
+ logging.error(str(e))
@options([
make_option('-u', '--username', type="str", help="Username of the user"),
@@ -793,8 +815,9 @@ class CLI(Cmd):
print("Deployment policy updated successfully")
else:
print("Error updating Deployment policy")
- except AuthenticationError as e:
- self.perror("Authentication Error")
+ except BadResponseError as e:
+ self.perror(str(e))
+ logging.error(str(e))
@options([
make_option('-u', '--username', type="str", help="Username of the user"),
@@ -812,8 +835,9 @@ class CLI(Cmd):
print("Successfully deleted deployment policy : "+deployment_policy_id)
else:
print("Could not deleted deployment policy : "+deployment_policy_id)
- except AuthenticationError as e:
- self.perror("Authentication Error")
+ except BadResponseError as e:
+ self.perror(str(e))
+ logging.error(str(e))
"""
# Deployment Policies
@@ -876,8 +900,9 @@ class CLI(Cmd):
print("Deployment policy added successfully")
else:
print("Error creating application policy")
- except AuthenticationError as e:
- self.perror("Authentication Error")
+ except BadResponseError as e:
+ self.perror(str(e))
+ logging.error(str(e))
@options([
make_option('-u', '--username', type="str", help="Username of the user"),
@@ -896,8 +921,9 @@ class CLI(Cmd):
print("Deployment policy updated successfully")
else:
print("Error updating Deployment policy")
- except AuthenticationError as e:
- self.perror("Authentication Error")
+ except BadResponseError as e:
+ self.perror(str(e))
+ logging.error(str(e))
@options([
make_option('-u', '--username', type="str", help="Username of the user"),
@@ -915,8 +941,9 @@ class CLI(Cmd):
print("Successfully deleted application policy : "+application_policy_id)
else:
print("Could not deleted application policy : "+application_policy_id)
- except AuthenticationError as e:
- self.perror("Authentication Error")
+ except BadResponseError as e:
+ self.perror(str(e))
+ logging.error(str(e))
"""
@@ -978,8 +1005,9 @@ class CLI(Cmd):
print("Network partition added successfully")
else:
print("Error creating network partition")
- except AuthenticationError as e:
- self.perror("Authentication Error")
+ except BadResponseError as e:
+ self.perror(str(e))
+ logging.error(str(e))
@options([
make_option('-u', '--username', type="str", help="Username of the user"),
@@ -998,8 +1026,9 @@ class CLI(Cmd):
print("Network partition updated successfully")
else:
print("Error updating Network partition")
- except AuthenticationError as e:
- self.perror("Authentication Error")
+ except BadResponseError as e:
+ self.perror(str(e))
+ logging.error(str(e))
@options([
make_option('-u', '--username', type="str", help="Username of the user"),
@@ -1017,8 +1046,9 @@ class CLI(Cmd):
print("Successfully deleted network-partition : "+network_partition_id)
else:
print("Could not deleted network-partition : "+network_partition_id)
- except AuthenticationError as e:
- self.perror("Authentication Error")
+ except BadResponseError as e:
+ self.perror(str(e))
+ logging.error(str(e))
"""
# Auto-scaling policies
@@ -1081,8 +1111,9 @@ class CLI(Cmd):
print("Autoscaling policy updated successfully:")
else:
print("Error updating Autoscaling policy")
- except AuthenticationError as e:
- self.perror("Authentication Error")
+ except BadResponseError as e:
+ self.perror(str(e))
+ logging.error(str(e))
@options([
make_option('-u', '--username', type="str", help="Username of the user"),
@@ -1100,8 +1131,9 @@ class CLI(Cmd):
print("Successfully deleted Auto-scaling policy : "+autoscaling_policy_id)
else:
print("Auto-scaling policy not found : "+autoscaling_policy_id)
- except AuthenticationError as e:
- self.perror("Authentication Error")
+ except BadResponseError as e:
+ self.perror(str(e))
+ logging.error(str(e))
"""
# Kubernetes clusters/hosts
@@ -1187,8 +1219,9 @@ class CLI(Cmd):
print("You have successfully deployed host to Kubernetes cluster: "+kubernetes_cluster_id)
else:
print("Error deploying host to Kubernetes cluster: "+kubernetes_cluster_id)
- except AuthenticationError as e:
- self.perror("Authentication Error")
+ except BadResponseError as e:
+ self.perror(str(e))
+ logging.error(str(e))
@options([
make_option('-u', '--username', type="str", help="Username of the user"),
@@ -1230,8 +1263,9 @@ class CLI(Cmd):
print("Kubernetes master updated successfully")
else:
print("Error updating Kubernetes master")
- except AuthenticationError as e:
- self.perror("Authentication Error")
+ except BadResponseError as e:
+ self.perror(str(e))
+ logging.error(str(e))
@options([
make_option('-u', '--username', type="str", help="Username of the user"),
@@ -1251,8 +1285,9 @@ class CLI(Cmd):
print("You have succesfully updated host to Kubernetes cluster")
else:
print("Error updating Kubernetes host")
- except AuthenticationError as e:
- self.perror("Authentication Error")
+ except BadResponseError as e:
+ self.perror(str(e))
+ logging.error(str(e))
@options([
make_option('-u', '--username', type="str", help="Username of the user"),
@@ -1270,8 +1305,9 @@ class CLI(Cmd):
print("Successfully un-deployed kubernetes cluster : "+kubernetes_cluster_id)
else:
print("Kubernetes cluster not found : "+kubernetes_cluster_id)
- except AuthenticationError as e:
- self.perror("Authentication Error")
+ except BadResponseError as e:
+ self.perror(str(e))
+ logging.error(str(e))
@options([
make_option('-u', '--username', type="str", help="Username of the user"),
@@ -1291,8 +1327,9 @@ class CLI(Cmd):
print("Successfully un-deployed kubernetes host : "+opts.host_id)
else:
print("Kubernetes host not found : "+opts.cluster_id+"/"+opts.host_id)
- except AuthenticationError as e:
- self.perror("Authentication Error")
+ except BadResponseError as e:
+ self.perror(str(e))
+ logging.error(str(e))
"""
@@ -1342,8 +1379,9 @@ class CLI(Cmd):
print(" Domain mapping added successfully")
else:
print("Error creating domain mapping")
- except AuthenticationError as e:
- self.perror("Authentication Error")
+ except BadResponseError as e:
+ self.perror(str(e))
+ logging.error(str(e))
@options([
@@ -1362,8 +1400,9 @@ class CLI(Cmd):
print("You have successfully deleted domain: "+domain)
else:
print("Could not delete domain: "+domain)
- except AuthenticationError as e:
- self.perror("Authentication Error")
+ except BadResponseError as e:
+ self.perror(str(e))
+ logging.error("HTTP "+e.error_code+" : "+str(e))
@options([
make_option('-u', '--username', type="str", help="Username of the user"),
@@ -1382,6 +1421,6 @@ class CLI(Cmd):
print("Autoscaling policy added successfully")
else:
print("Error adding autoscaling policy")
- except AuthenticationError as e:
- self.perror("Authentication Error")
-
+ except BadResponseError as e:
+ self.perror(str(e))
+ logging.error(str(e))
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/stratos/blob/b37cac82/components/org.apache.stratos.python.cli/src/main/python/cli/Stratos.py
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.python.cli/src/main/python/cli/Stratos.py b/components/org.apache.stratos.python.cli/src/main/python/cli/Stratos.py
index 4fcbecb..d1a300d 100755
--- a/components/org.apache.stratos.python.cli/src/main/python/cli/Stratos.py
+++ b/components/org.apache.stratos.python.cli/src/main/python/cli/Stratos.py
@@ -18,8 +18,7 @@
import requests
import json
import Configs
-from Logging import logging
-from cli.exceptions.AuthenticationError import AuthenticationError
+from cli.exceptions.BadResponseError import BadResponseError
class Stratos:
@@ -424,30 +423,10 @@ class Stratos:
try:
Stratos.get('init')
return True
- except AuthenticationError as e:
+ except BadResponseError as e:
return False
@staticmethod
- def get(resource, error_message=""):
- r = requests.get(Configs.stratos_api_url + resource,
- auth=(Configs.stratos_username, Configs.stratos_password), verify=False)
- print(r)
- print(r.text)
- if r.status_code == 200:
- return r.json()
- elif r.status_code == 400:
- raise requests.HTTPError()
- elif r.status_code == 401:
- raise AuthenticationError()
- elif r.status_code == 404:
- if r.text and r.json() and r.json()['message'] == error_message:
- return False
- else:
- raise requests.HTTPError()
- else:
- logging.error(r.status_code+" : "+r.text)
-
- @staticmethod
def delete(resource, error_message=None):
r = requests.delete(Configs.stratos_api_url + resource,
auth=(Configs.stratos_username, Configs.stratos_password), verify=False)
@@ -456,9 +435,9 @@ class Stratos:
if r.status_code == 200:
return r.json()
elif r.status_code == 400:
- raise requests.HTTPError()
+ raise BadResponseError(str(r.status_code), r.json()['message'])
elif r.status_code == 401:
- raise AuthenticationError()
+ raise BadResponseError(str(r.status_code), r.json()['message'])
elif r.status_code == 404:
if r.text and r.json() and r.json()['message']:
return False
@@ -466,9 +445,9 @@ class Stratos:
if r.text and r.json() and r.json()['message']:
return False
else:
- raise requests.HTTPError()
+ raise BadResponseError(str(r.status_code), r.json()['message'])
else:
- logging.error(r.status_code+" : "+r.text)
+ raise BadResponseError(str(r.status_code), r.json()['message'])
@staticmethod
def post(resource, data, error_message=None):
@@ -482,16 +461,16 @@ class Stratos:
elif r.status_code == 201:
return True
elif r.status_code == 400:
- raise requests.HTTPError()
+ raise BadResponseError(str(r.status_code), r.json()['message'])
elif r.status_code == 401:
- raise AuthenticationError()
+ raise BadResponseError(str(r.status_code), r.json()['message'])
elif r.status_code == 404:
if r.text and r.json() and r.json()['message'] == error_message:
return []
else:
- raise requests.HTTPError()
+ raise BadResponseError(str(r.status_code), r.text)
else:
- logging.error(r.status_code+" : "+r.text)
+ raise BadResponseError(str(r.status_code), r.json()['message'])
@staticmethod
def put(resource, data, error_message):
@@ -505,16 +484,16 @@ class Stratos:
elif r.status_code == 201:
return True
elif r.status_code == 400:
- raise requests.HTTPError()
+ raise BadResponseError(str(r.status_code), r.json()['message'])
elif r.status_code == 401:
- raise AuthenticationError()
+ raise BadResponseError(str(r.status_code), r.json()['message'])
elif r.status_code == 404:
if r.text and r.json() and r.json()['message'] == error_message:
return []
else:
- raise requests.HTTPError()
+ raise BadResponseError(str(r.status_code), r.json()['message'])
else:
- logging.error(r.status_code+" : "+r.text)
+ raise BadResponseError(str(r.status_code), r.json()['message'])
@staticmethod
@@ -526,3 +505,24 @@ class Stratos:
return Stratos.post('applications', json, error_message='No application found')
+def get(resource, error_message=""):
+ r = requests.get(Configs.stratos_api_url + resource,
+ auth=(Configs.stratos_username, Configs.stratos_password), verify=False)
+ print(r)
+ print(r.text)
+ if r.status_code == 200:
+ return r.json()
+ elif r.status_code == 400:
+ raise BadResponseError(str(r.status_code), r.json()['message'])
+ elif r.status_code == 401:
+ raise BadResponseError(str(r.status_code), r.json()['message'])
+ elif r.status_code == 404:
+ if r.text and r.json() and r.json()['message'] == error_message:
+ return False
+ else:
+ raise BadResponseError(str(r.status_code), " : "+r.text)
+ else:
+ raise BadResponseError(str(r.status_code), r.json()['message'])
+ return response(r)
+
+
http://git-wip-us.apache.org/repos/asf/stratos/blob/b37cac82/components/org.apache.stratos.python.cli/src/main/python/cli/exceptions/AuthenticationError.py
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.python.cli/src/main/python/cli/exceptions/AuthenticationError.py b/components/org.apache.stratos.python.cli/src/main/python/cli/exceptions/AuthenticationError.py
deleted file mode 100644
index 5bcd5d8..0000000
--- a/components/org.apache.stratos.python.cli/src/main/python/cli/exceptions/AuthenticationError.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-class AuthenticationError(Exception):
- def __init__(self, message=""):
- pass
-
- def __str__(self):
- return "Authentication error"
http://git-wip-us.apache.org/repos/asf/stratos/blob/b37cac82/components/org.apache.stratos.python.cli/src/main/python/cli/exceptions/BadResponseError.py
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.python.cli/src/main/python/cli/exceptions/BadResponseError.py b/components/org.apache.stratos.python.cli/src/main/python/cli/exceptions/BadResponseError.py
new file mode 100644
index 0000000..775ec65
--- /dev/null
+++ b/components/org.apache.stratos.python.cli/src/main/python/cli/exceptions/BadResponseError.py
@@ -0,0 +1,24 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+class BadResponseError(Exception):
+ def __init__(self, error_code, message=""):
+ self.error_code = error_code
+ self.message = message
+
+ def __str__(self):
+ return self.message