Dealing with an AWS S3 bucket file not found error: A comprehensive guide

My image route uses a controller like this:

public getImage(request: Request, response: Response): Response {
    try {
        const key = request.params.key;
        const read = getFileStream(key);

        return read.pipe(response);
    } catch (error) {
        return response.status(404).json({
            message: 'Image not found.'
        });
    }
}

Additionally, I have the following function:

// aws.ts

export function getFileStream(fileKey: any) {
    const downloadParams = {
        Key: fileKey,
        Bucket: bucketName
    };

    return s3.getObject(downloadParams).createReadStream();
}

However, I encounter an issue when I provide a key that doesn't exist in the S3 bucket. The try/catch block does not handle this scenario, causing my app to crash with an 'Access denied' error code. How can I resolve this situation? Thank you! 😁

Answer №1

In order to ensure that the key refers to a valid object, I first validate it by retrieving the object data before attempting to access the object itself. If the object does not exist, an error is thrown which can be caught, as shown below:

// aws.ts

export async function getFileStream(key: string) {
    const downloadParams = {
        Key: key,
        Bucket: bucketName
    };

    try {
        // Check if object exists
        const head = await s3.headObject(downloadParams).promise();

        // Return the object
        return s3.getObject(downloadParams).createReadStream();
    } catch (headErr: any) {
        // Return null if an error occurs
        return null;
    }
}

Then, in the controller:

public async getFile(request: Request, response: Response) {
    const key = request.params.key;

    const read = await getFileStream(key);

    if (read != null) return read.pipe(response);
    else return response.sendStatus(404);
}

Make sure to include the list bucket option in your S3 policy, as it is required to use the headObject() method. Below is an example of the policy needed:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:DeleteObject",
                // The following actions are required
                "s3:GetObject",
                "s3:ListBucket",
            ],
            "Resource": [
                "arn:aws:s3:::YOUR-BUCKET-NAME-HERE",
                "arn:aws:s3:::YOUR-BUCKET-NAME-HERE/*"
            ]
        }
    ]
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Encountering a Typescript error while attempting to utilize mongoose functions

An example of a User interface is shown below: import {Document} from "mongoose"; export interface IUser extends Document{ email: string; password: string; strategy: string; userId: string; isValidPassword(password: string): ...

Exploring the usage of array map parameters in rxjs 6 when combined with withLatestFrom

Prior to Rxjs 6, we were able to achieve the following: interface TypeA { payload: any; } source$.pipe( withLatestFrom(source2$, (source1: TypeA, source2: TypeB) => ({ payload: source1.payload, source2 }) ), ) In the resultSelector method ...

Having difficulty implementing dynamic contentEditable for inline editing in Angular 2+

Here I am facing an issue. Below is my JSON data: data = [{ 'id':1,'name': 'mr.x', },{ 'id':2,'name': 'mr.y', },{ 'id':3,'name': 'mr.z', },{ & ...

Utilizing Node Express for RESTful API creates a seamless error handling system

I have been working on developing a series of RESTful API services using Node.js Express. Whenever an error occurs, it is accompanied by a stack-trace with the following message: Error: No default engine was specified and no extension was provided. I h ...

Tips for injecting a service into a class (not a component)

Can you inject a service into a class that is not a component? Consider the following scenario: Myservice import {Injectable} from '@angular/core'; @Injectable() export class myService { dosomething() { // implementation } } MyClass im ...

Implement a separate module for all routes on express.js version 4

Currently, I am utilizing Express version 4.2.0. Is there a way to import a module only one time in app.js and utilize it across any defined route? At the moment, this approach doesn't seem to work: app.js //.. var request = require('request& ...

Mongoose: implement the schema from another model

I have a model 'Template' which I need to maintain its history in another model called 'TemplateHistory'. Instead of redefining the schema, how can I utilize the existing Template Schema for the HistorySchema? var Schema = new mongoose ...

The onSubmit function in React JavaScript is failing to execute, it is not triggering and no error message is being displayed on the frontend console

As a newcomer to React.js, I recently came across an article detailing how to perform CRUD operations with React Express and MongoDB. However, after implementing the code, I encountered an issue when trying to add a user. Upon clicking the 'Save' ...

What is the reason behind the Typescript compiler not converting .ts files to .js files automatically?

Displayed below are the folders on the left showcasing my Typescript file in /src (blue) compiled into Javascript in /dist (purple) using tsc. https://i.stack.imgur.com/7XNkU.png In the source file on the left, there is a reference to a .ts module file t ...

Utilizing various settings using `.env` files in NodeJs

As I work on building a backend in nodejs, one of the key considerations is how to incorporate an environment configuration into the project. I am envisioning a structure where there is a /config folder housing my envparser.ts (still brainstorming a catchi ...

The element is implicitly assigned the 'any' type due to the inability to use an expression of type to index the element

Check out my TS playground here // I have colours const colors = { Red: "Red", Blue: "Blue", Green: "Green" } type TColor = keyof typeof colors; // Some colours have moods associated with them const colorsToMood = { ...

removing the mapStateToProps function will result in an undefined value

I am new to React and I'm in the process of converting a class component to functional components using hooks. I need some guidance on safely removing 'mapStateToProps' without encountering undefined errors. I have two pages, A.js and B.js. ...

The state may be modified, but the component remains unchanged

I've been tasked with implementing a feature on a specific website. The website has a function for asynchronously retrieving data (tickets), and I need to add a sorting option. The sorting process occurs on the server side, and when a user clicks a s ...

Having trouble with sending values to Angular 7 components' HTML pages

Struggling with a simple task and encountering an error: Code snippet below: app.component.html <div class="col-md-{{myvalue}}">stuff here</div> app.component.ts myvalue: string; ngOnInit() { this.myvalue('6'); } Seeing th ...

What are the recommended guidelines for using TypeScript effectively?

When facing difficulties, I have an array with functions, such as: this._array = [handler, func, type] How should I declare this private property? 1. Array<any> 2. any[] 3. T[] 4. Array<T> What is the difference in these declarations? ...

The "isActive" value does not share any properties with the type 'Properties<string | number, string & {}>'. This issue was encountered while using React with TypeScript

I'm attempting to include the isActive parameter inside NavLink of react-router-dom version 5, but I'm encountering two errors. The type '({ isActive }: { isActive: any; }) => { color: string; background: string; }' does not have an ...

Transition your Sequelize migrations to TypeORM

I'm currently in the process of transitioning a Node.js application from vanilla JS to Nest.js. In our previous setup, we used Sequelize as our ORM, but now we've decided to switch to TypeORM for its improved type safety. While exploring the Type ...

Errors in Ionic 6 involving the FormBuilder, FormGroup, Validators, FormControl, and ControlContainer

I am currently working on creating a basic registration form using Ionic 6.12.3 ionic -V, Angular CLI version 11.0.5, and npm version 6.14.11. You can find the repository for this project here: Repo. Below is my implementation for the register.page.ts: // ...

Looking for another alternative to discord.js EvaluatedPermissions?

Before when I was using v11.x.x, my dashboard.js had a section that looked like this: const perms = Discord.EvaluatedPermissions; renderTemplate(res, req, "dashboard.ejs", {perms}); However, after updating the bot to discord.js v12, 'perms&a ...

Generating output from a callback function in TypeScript

When I execute a graphql query, the showUsers function is supposed to display all users (styled as boxes). However, at the moment, nothing is showing up. I am utilizing a functional component instead of a class component. This function is invoked after m ...