I am new to python. Is there anyway I can raise error in Lambda function? I have a pyqt5 button that connect to a lambda function. I would like to catch the error in lambda function and show it to user. Is there anyway I can bring the message(string) out of the lambda function and then show it to user or is there anyway I can raise an error inside lambda function? I have a try/except in the place where lambda was apply. What I hope is when the lambda function have error and the error can be catch outside of the lambda function.
example:
def test1:
*****
def test2(a):
****
try:
x=lambda(test2(test1))
except Exception as e:
print(e) <<< want it to go here.
In your code you only assign a lambda function to a variable without any calling. In addition, the syntax for lambda seems to be wrong. You could change your code something like as follows:
def test1:
*****
def test2(a):
****
a_func = lambda x: test2(test1(x))
try:
a_func(some_input)
except Exception as e:
print(e)
import os
import boto3
import json
from botocore.exceptions import ClientError
def lambda_handler(event, context):
# Fetch Datebase Identifier Environment variable
DBinstance = os.environ['DBInstanceName']
#create an Rds client
context.rds_client = boto3.client('rds')
# Describe instance
response = context.rds_client.describe_db_instances(DBInstanceIdentifier=DBinstance )
#Check the status of rds instance
status = response['DBInstances'][0]['DBInstanceStatus']
# If Rds Instance is in stopped stop, It will be started
if status == "stopped":
try:
#Stopping the Rds instance
response = context.rds_client.start_db_instance( DBInstanceIdentifier=DBinstance )
#send logs to cloudwatch
print ('Success :: Starting Rds instance:', DBinstance)
#Logs to Lambda function Execution results
return {
'statusCode': 200,
'message': "Starting Rds instance",
'body': json.dumps(response, default=str)
}
except ClientError as e:
#send logs to cloudwatch
print(e)
message = e
#Logs to Lambda function Execution results
return {
'message': "Script execution completed. See Cloudwatch logs for complete output, but instance starting failed",
'body': json.dumps(message, default=str)
}
# if Rds instance is in running state, It will be stopped
elif status == "available":
try:
#Stopping the Rds instance
response = context.rds_client.stop_db_instance( DBInstanceIdentifier=DBinstance )
#send logs to cloudwatch
print ('Success :: Stopping Rds instance:', DBinstance)
#Logs to Lambda function Execution results
return {
'statusCode': 200,
'message': "Stopping Rds instance",
'body': json.dumps(response, default=str)
}
except ClientError as e:
#send logs to cloudwatch
print(e)
message = e
#Logs to Lambda function Execution results
return {
'message': "Script execution completed. See Cloudwatch logs for complete output, but instance stopping failed",
'body': json.dumps(message, default=str)
}
Related
I am developing an API for an app with python, using FastAPI, serverless and amazon web services.
We are using CloudWatch for saving our logs.
The thing is, I am required to send different logs to different groups in the same aplication, depending on wethever is it an error, an info, etc.
Let´s say, I have two log groups in CloudWatch: /aws/lambda/firstGroup and /aws/lambda/secondGroup.
An I have this function:
def foo(some_data):
logger.info(f'calling the function with the data: {data}') # this goes to logGroup /aws/lambda/firstGroup
try:
doSomething()
except:
logger.error('ERROR! Something happened') # this goes to logGroup /aws/lambda/secondGroup
How can I configure the serverless.yml file so the logger.info goes to the first group and the logger.error goes to the second group?
Thanks in advance!
I am using this solution with ec2 instance.
create a log group
create log stream
then dump your logs
import boto3
import time
# init clients
clw_client = boto3.client('logs', region_name=REGION)
# print("check else create new log group..")
try:
clw_client.create_log_group(logGroupName=LOG_GROUP)
except clw_client.exceptions.ResourceAlreadyExistsException:
pass
# print("check else create new log stream.....")
LOG_STREAM = '{}-{}'.format(time.strftime("%m-%d-%Y-%H-%M-%S"),'logstream')
try:
clw_client.create_log_stream(logGroupName=LOG_GROUP, logStreamName=LOG_STREAM)
except clw_client.exceptions.ResourceAlreadyExistsException:
pass
def log_update(text):
print(text)
response = clw_client.describe_log_streams(
logGroupName = LOG_GROUP,
logStreamNamePrefix = LOG_STREAM
)
try:
event_log = {
'logGroupName': LOG_GROUP,
'logStreamName': LOG_STREAM,
'logEvents': [{
'timestamp': int(round(time.time() * 1000)),
'message': f"{time.strftime('%Y-%m-%d %H:%M:%S')}\t {text}"
}
],
}
if 'uploadSequenceToken' in response['logStreams'][0]:
event_log.update({'sequenceToken': response['logStreams'][0] ['uploadSequenceToken']})
response = clw_client.put_log_events(**event_log)
except Exception as e:
log_update(e)
Then use call that function inside your app whenever you like. Just don't check for groups and stream again and again for one job, these should run once.
You can update it, add more logic like change log-group name to implement what you wanted in this question with just some if else statements. Good luck!
I have a lambda function that will read an excel file and do some stuffs and then store the result in a different S3 bucket.
def lambda_handler(event, context):
try:
status = int(event['status'])
if status:
Reading_Bucket_Name = 'read-data-s3'
Writing_Bucket_Name = 'write-excel-file-bucket'
rowDataFile = 'Analyse.xlsx'
HTMLfileName = 'index.html'
url = loading_function(Reading_Bucket_Name=Reading_Bucket_Name, Writing_Bucket_Name=Writing_Bucket_Name, rowDataFile=rowDataFile, HTMLfileName=HTMLfileName)
status = 0
return {"statusCode": 200, "URL": url}
else:
return {"statusCode": 400, "Error": "The code could not be executed"}
except Exception as e:
print('#________ An error occurred while reading Status code int(event[status]) ________#')
print(e)
raise e
return None
The code is only supposed to work once! And that it returns the URL and then turns off and exit the Lambda function.
But the problem is: I will get the first output, and then the lambda function will call itself again! And it will go to the exception and execute it at least many times! Because there is no event['status']. 'This must be received if I call this function by:
{
"status": "1"
}
How can I stop execution after getting the first output?
Update:
This will cause the problem by uploading a new file to an S3 bucket:
s3_client = boto3.client('s3')
fig.write_html('/tmp/' + HTMLfileName, auto_play=False)
response = s3_client.upload_file('/tmp/' + HTMLfileName, Writing_Bucket_Name, HTMLfileName, ExtraArgs={'ACL':'public-read', 'ContentType':'text/html'})
return True
Given that the Lambda function appears to be running when a new object is created in the Amazon S3 bucket, it would appear that the bucket has been configured with an Event Notification that is triggering the AWS Lambda function.
To check this, go the to bucket in the S3 management console, go to the Properties tab and scroll down to Event notifications. Look for any configured events that trigger a Lambda function.
I would like to be able to see in Cloudwatch metrics (and Lambda metrics) errors for handle exception.
For the moment I see the errors only in Cloudwatch log group for handled errors.
Here is the code I use in my Lambda
def lambda_handler(event, context):
try:
raise Exception("My exeception")
except Exception as e:
logger.exception(str(e))
continue
And my logger is defined like this
import logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)
With this configuration I can just see errors in my logs group, but not in the lamda/cloudwatch metrics
According to your given code snippet, the lambda execution was completed successfully.
To track the failure and success you've to just raise the exception in case of failure and handle it in case of success.
def lambda_handler(event, context):
# try:
raise Exception("My exception")
# except Exception as e:
# logger.exception(str(e))
# continue
The logger will show all the logged error/success messages in the stream.
So, if you'll handle the error, then it won't be a failure execution hence no failure on the graph.
I created a aws lambda function and trying to integrate it with AWS Connect.
The lambda function resets the directory password. AWS Connect triggers the lambda function, the function reset the password and signal AWS Connect success or failed. How do I include signal in the code?
import logging
import json
import boto3
client = boto3.client('ds')
def lambda_handler(event, context):
response = reset_user_password()
return event
def reset_user_password():
response = client.reset_user_password(
DirectoryId='d-xxxxxxxxxx',
UserName='username',
NewPassword='Password'
)
Unclear what you mean by signal, but you can add visibility into the response or error message with something like this for your reset function:
def reset_user_password():
try:
response = client.reset_user_password(
DirectoryId='d-xxxxxxxxxx',
UserName='username',
NewPassword='Password'
)
print(response)
except Exception as e:
print(e)
response = str(e)
return response
Also, you are calling the reset function in the lambda handler before it is defined, which will throw an error. You need to update the code like this:
import logging
import json
import boto3
client = boto3.client('ds')
def reset_user_password():
try:
response = client.reset_user_password(
DirectoryId='d-xxxxxxxxxx',
UserName='username',
NewPassword='Password'
)
print(response)
except Exception as e:
print(e)
response = str(e)
return response
def lambda_handler(event, context):
response = reset_user_password()
return response
I'm completely new with AWS Lex and AWS Lambda, so it's a beginner question.
I'm trying to create a bot that helps a user choose bikes. The first question is what type of bike the user needs and the answers are men/women/unisex/kids.
I'm trying to write a lambda validation function so that the bot will tell the user when the choice he entered is none of those mentioned above.
The error I receieve is:
An error has occurred: Invalid Lambda Response: Received error
response from Lambda (LambdaRequestId:
471e1df7-034c-46e7-9154-23de79cb16cf; Error: Unhandled)
And this is the code:
import json
def get_slots(intent_request):
return intent_request['currentIntent']['slots']
def valid_bike_type(intent_request):
bike_type=get_slots(intent_request)['BikeType']
bike_types_lst = ['men', 'women', 'unisex', 'kids']
if bike_type is not None and bike_type.lower() not in bike_types_lst:
return build_validation_result(False, 'BikeType', 'We only have bikes for Men/Women/Unisex/Kids.')
return build_validation_result(True, None, None)
def dispatch(intent_request):
intent_name = intent_request['currentIntent']['name']
if intent_name == 'WelcomeIntent':
return valid_bike_type(intent_request)
raise Exception('Intent with name' + intent_name + ' not supported.')
def lambda_handler(event, context):
return dispatch(event)
Thank you very much for any help!
You can just use print as you would usually do on your workstation, e.g.:
def lambda_handler(event, context):
print(event)
return dispatch(event)
The outcome of print, or any other function that prints to stdout, will be in CloudWatch Logs as explained in AWS docs:
Lambda automatically integrates with CloudWatch Logs and pushes all logs from your code to a CloudWatch Logs group associated with a Lambda function, which is named /aws/lambda/.
For Lex, you can also check documentation about Lambda's input and output, or check avaiable blueprints.
found some information on AWS docs about unhandled errors:
I would check first the lambda settings: Memory and Timeout (as the default is only 3 sec).
You can edit these settings using AWS console, in the lambda configuration, under the 'Basic Settings' tab.