Skip to content

Commit

Permalink
Better errors for file too big/too many files
Browse files Browse the repository at this point in the history
  • Loading branch information
viral32111 committed Jan 9, 2023
1 parent 7476cf5 commit 8418fc1
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 19 deletions.
5 changes: 4 additions & 1 deletion Client/scripts/helpers/serverErrorCodes.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ const serverErrorCodeMessages = {
12: "No files uploaded",
13: "No data available",
14: "Failed to perform operation(s) on the database",
15: "WebSocket failed to broadcast payload"
15: "WebSocket failed to broadcast payload",
16: "You have uploaded too many files",
17: "One or more of the files you uploaded is too large",
18: "Failed to upload file(s)"
}

// Shows the feedback modal for a server API error
Expand Down
5 changes: 4 additions & 1 deletion Server/source/enumerations/errorCodes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,8 @@ export enum ErrorCodes {
NoFilesUploaded = 12,
NoData = 13,
DatabaseOperationFailure = 14,
BroadcastFailure = 15
BroadcastFailure = 15,
UploadTooManyFiles = 16,
UploadFileTooLarge = 17,
UploadFailed = 18
}
1 change: 1 addition & 0 deletions Server/source/enumerations/httpStatusCodes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export enum HTTPStatusCodes {
BadRequest = 400,
Unauthorized = 401,
Forbidden = 403,
PayloadTooLarge = 413,
UpgradeRequired = 426,
InternalServerError = 500,
NotImplemented = 501
Expand Down
70 changes: 53 additions & 17 deletions Server/source/routes/chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { getLogger } from "log4js"
import { ObjectId } from "mongodb"
import { Request } from "express"
import { RawData, WebSocket } from "ws"
import { MulterError } from "multer"

// Import code from other scripts
import { expressApp, webSocketServer, multerMiddleware } from "../main"
Expand Down Expand Up @@ -45,7 +46,8 @@ expressApp.get( "/api/chat", ( request, response ) => {
} )

// Route for uploading files to use as message attachments
expressApp.put( "/api/upload", multerMiddleware.any(), ( request, response ) => {
const multerRequestHandler = multerMiddleware.any()
expressApp.put( "/api/upload", ( request, response ) => {

// Fail if the guest has not chosen a name yet
if ( request.session.guestId === undefined ) return respondToRequest( response, HTTPStatusCodes.Unauthorized, {
Expand All @@ -62,26 +64,60 @@ expressApp.put( "/api/upload", multerMiddleware.any(), ( request, response ) =>
error: ErrorCodes.InvalidContentType
} )

// Fail if no files were uploaded
if ( request.files === undefined ) return respondToRequest( response, HTTPStatusCodes.BadRequest, {
error: ErrorCodes.NoFilesUploaded
} )
// Attempt to receive any uploaded files
multerRequestHandler( request, response, ( error ) => {

// If there was an Multer-specific error...
if ( error instanceof MulterError ) {
log.error( `Failed to handle uploaded files for guest '${ request.session.guestId }' in room '${ request.session.roomId } (${ error.message })!'` )

// Respond based on the type of error - https://github.com/expressjs/multer/blob/master/lib/multer-error.js
if ( error.code === "LIMIT_PART_COUNT" || error.code === "LIMIT_FILE_COUNT" || error.code === "LIMIT_FIELD_COUNT" ) {
return respondToRequest( response, HTTPStatusCodes.PayloadTooLarge, {
error: ErrorCodes.UploadTooManyFiles
} )
} else if ( error.code === "LIMIT_FILE_SIZE" || error.code === "LIMIT_FIELD_VALUE" ) {
return respondToRequest( response, HTTPStatusCodes.PayloadTooLarge, {
error: ErrorCodes.UploadFileTooLarge
} )
} else {
return respondToRequest( response, HTTPStatusCodes.BadRequest, {
error: ErrorCodes.UploadFailed
} )
}

// If there was a generic error...
} else if ( error ) {
log.error( `Failed to process uploaded files for guest '${ request.session.guestId }' in room '${ request.session.roomId } (${ error })!'` )
return respondToRequest( response, HTTPStatusCodes.BadRequest, {
error: ErrorCodes.UploadFailed
} )
}

// Cast because TypeScript doesn't know how to do this automatically
const uploadedFiles = request.files as Express.Multer.File[]
// If we got to this point, then no errors occured

// Loop through the uploaded files & add their type and URL to a payload for the response
const filesPayload: Attachment[] = []
for ( const file of uploadedFiles ) filesPayload.push( {
type: file.mimetype,
path: `/attachments/${ file.filename }`
} )
// Fail if no files were uploaded
if ( request.files === undefined || request.files.length <= 0 ) return respondToRequest( response, HTTPStatusCodes.BadRequest, {
error: ErrorCodes.NoFilesUploaded
} )

// Cast because TypeScript doesn't know how to do this automatically
const uploadedFiles = request.files as Express.Multer.File[]

// Loop through the uploaded files & add their type and URL to a payload for the response
const filesPayload: Attachment[] = []
for ( const file of uploadedFiles ) filesPayload.push( {
type: file.mimetype,
path: `/attachments/${ file.filename }`
} )

// Send back the list of uploaded files
respondToRequest( response, HTTPStatusCodes.OK, {
files: filesPayload
} )
log.info( `Guest '${ request.session.guestId }' uploaded ${ uploadedFiles } files.` )

// Send back the list of uploaded files
respondToRequest( response, HTTPStatusCodes.OK, {
files: filesPayload
} )
log.info( `Guest '${ request.session.guestId }' uploaded ${ uploadedFiles } files.` )

} )

Expand Down

0 comments on commit 8418fc1

Please sign in to comment.