#typescript #asynchronous #amazon-s3 #aws-lambda #amazon-dynamodb
#typescript #асинхронный #amazon-s3 #aws-lambda #amazon-dynamodb
Вопрос:
Привет, я пишу асинхронную функцию на основе typescript (aws lambda function) для обработки данных в aws s3 с помощью s3.selectObjectContent и записываю извлеченное значение в таблицу в dynamodb при использовании dyanmodb.PutItem. Я получаю сообщение об ошибке, когда обрабатываются данные s3, но функция (при асинхронном вызове) все еще завершает запись в таблицу базы данных. По какой-то причине переменная, в которой хранятся данные полезной нагрузки s3, сообщается как неопределенная до завершения команды s3 и возврата обещания. Можете ли вы помочь мне найти лучший способ написания этого кода или предложить, как я могу это исправить?
export class Handler {
import { S3, DynamoDB } from 'aws-sdk'
import { DID_TABLENAME, IP_DEVICE_HISTORY_TABLENAME } from './Constants'
dynamodb = new DynamoDB()
s3 = new S3()
async handle(event: SQSEvent): Promise<void> {
console.log('Entering handler')
console.log(event)
this.srcBucket = 'my-bucket'
this.srcKey = 'myfile.gzip'
await this.prepareAndQuery()
}
private async prepareAndQuery(): Promise<any> {
console.log('Preparing params')
const params = {
Bucket: this.srcBucket,
Key: this.srcKey,
ExpressionType: 'SQL',
Expression: 'SELECT * FROM s3object',
InputSerialization: { CompressionType: 'GZIP', JSON: { Type: 'LINES' }},
OutputSerialization: { JSON: { RecordDelimiter: ' ' }}}
console.log('Sending s3 command')
try {
this.s3selectOutput = await this.s3.selectObjectContent(params).promise()
const events: any = this.s3selectOutput.Payload
for await (const event of events) {
try {
if(event.Records) {
// THIS LINE BELOW IS THE POINT OF FAILURE
const s3selectOutput: any = event.Records.Payload.toString()
const decoded = decodeURIComponent(s3selectOutput.replace(/ |t/g, ' '))
const jsoncontent = JSON.parse(decoded)
const udid = jsoncontent.pyAppResponse.logs.udid_logs.udid;
const did = jsoncontent.pyAppResponse.logs.udid_logs.did;
if ((did !== null) amp;amp; (udid !== null)) {
events.pause()
const paramsdiddB = {
Item: {
'did': { S: did },
'udid': { S: udid }},
ReturnConsumedCapacity: 'TOTAL',
TableName: DID_TABLENAME }
console.log(`going to write to dbs ${DID_TABLENAME}`)
const _retValue = await this.dynamodb.putItem(paramsdiddB).promise().then((_dBdata: any) => {
console.log(`Successfuly wrote to tables: ${DID_TABLENAME}`)
}).catch((dBerr: any) => {
console.log('Error writing to database tables')
console.log(dBerr.stack)
})
events.resume()
}
}
}
catch (s3undefinederr) {
if (s3undefinederr instanceof TypeError) {
console.log(s3undefinederr)
throw s3undefinederr
}
}
if (event.End !== null) {
console.log('SelectObjectContent completed')
}
}
}
catch (s3error) {
console.log(s3error)
throw s3error
}
return this.s3selectOutput
}
}
Сообщение об ошибке во время выполнения (даже если оно завершает работу!
at Handler.<anonymous> (/var/task/build/dist/Handler.js:144:66)
at Generator.next (<anonymous>)
at fulfilled (/var/task/build/dist/Handler.js:5:58)
at processTicksAndRejections (internal/process/task_queues.js:97:5)
2020-09-30T04:58:57.312Z 9783b6c9-d88e-4b14-82d0-607bd14ec730 ERROR Invoke Error {"errorType":"TypeError","errorMessage":"Cannot read property 'Payload' of undefined","stack":["TypeError: Cannot read property 'Payload' of undefined"," at Handler.<anonymous> (/var/task/build/dist/Handler.js:144:66)"," at Generator.next (<anonymous>)"," at fulfilled (/var/task/build/dist/Handler.js:5:58)"," at processTicksAndRejections (internal/process/task_queues.js:97:5)"]}```
Ответ №1:
Я смог исправить эту ошибку, обнаружив ошибку с помощью инструкции try catch, которая выглядит следующим образом
catch (s3undefinederr) {
console.log(s3undefinederr)
if (s3undefinederr instanceof Error) {
throw s3undefinederr
}
}