3
votes

The Situation

I'm using the aws-sdk to interact with an S3 bucket.

If I don't have the proper credentials set up, the sdk appropriately complains. However, its method of complaint is an error that is thrown outside of my call stack. I want to be able to catch that error and handle it gracefully.

The Problem

Here is a little script that causes the problem.

import { S3 } from 'aws-sdk';
try {
  const s3 = new S3();
  s3.createPresignedPost({}, (err, data) => {
    console.log('sup dog');
  });
} catch (err: Error) {
  console.log('KABOOM!');
}

I would expect this to catch any errors thrown by s3.createPresignedPost and trigger the catch, but what actually happens is sup dog is posted, and then node crashes with a stack trace that points to the aws-sdk.

sup dog
./node_modules/aws-sdk/lib/services/s3.js:1241
      throw new Error('Unable to create a POST object policy without a bucket,'
      ^

Error: Unable to create a POST object policy without a bucket, region, and credentials
    at features.constructor.preparePostFields (./node_modules/aws-sdk/lib/services/s3.js:1241:13)
    at finalizePost (./node_modules/aws-sdk/lib/services/s3.js:1204:22)
    at ./node_modules/aws-sdk/lib/services/s3.js:1221:24
    at finish (./node_modules/aws-sdk/lib/config.js:386:7)
    at ./node_modules/aws-sdk/lib/config.js:428:9
    at Object.<anonymous> (./node_modules/aws-sdk/lib/credentials/credential_provider_chain.js:111:13)
    at Object.arrayEach (./node_modules/aws-sdk/lib/util.js:516:32)
    at resolveNext (./node_modules/aws-sdk/lib/credentials/credential_provider_chain.js:110:20)
    at ./node_modules/aws-sdk/lib/credentials/credential_provider_chain.js:126:13
    at ./node_modules/aws-sdk/lib/credentials.js:124:23
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

The Question

The solution here of course is to properly configure the aws sdk with credentials, but I would like to gracefully handle cases where that hasn't happened by catching the error and preventing a hard crash.

How can I use the callback pattern of createPresignedPost without risking system crash?

2

2 Answers

0
votes

I have created this lambda request :

const AWS = require('aws-sdk');

const s3 = new AWS.S3();


exports.handler = async (event, context) => {
    //console.log('Received event:', JSON.stringify(event, null, 2));

    let body;
    let statusCode = '200';
    const headers = {
        'Content-Type': 'application/json',
    };
    var params = {
      Bucket: 'bucketname',
      Fields: {
        key: 'example.pdf'
      }
    };
    try {
        s3.createPresignedPost(params, (err, data) => {
            body = "successfully";
        });
    } catch (err) {
        statusCode = '400';
        body = err.message;
    } finally {
        body = JSON.stringify(body);
    }

    return {
        statusCode,
        body,
        headers,
    };
};

For testing success case run code as it is. For testing error comment params one of key either bucket or key. it will throw error and catch.

Response:
{
  "statusCode": "400",
  "body": "\"Unable to create a POST object policy without a bucket, region, and credentials\"",
  "headers": {
    "Content-Type": "application/json"
  }
}
0
votes

This turned out to be a full blown bug in AWS -- I issued a patch which was merged.

So, the answer to this question is that it wasn't possible to catch that error... but now you don't have to.