Skip to content

Commit

Permalink
Add notifications when there is an error in the service (#264)
Browse files Browse the repository at this point in the history
* Add detail error descriptions

* Fix exception occurrence

* Update JwtAuthGuard to handle token expiration and invalid token errors

* Update useErrorHandler to handle custom error responses

* Update error handling and exception messages

* Update error handler to handle custom error response

* Update JwtAuthGuard to handle exception with handleRequest

* Remove console.error in useErrorHandler
  • Loading branch information
wet6123 authored Aug 3, 2024
1 parent 8a95c62 commit 6b26087
Show file tree
Hide file tree
Showing 9 changed files with 65 additions and 19 deletions.
21 changes: 20 additions & 1 deletion backend/src/auth/jwt.guard.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import { ExecutionContext, Injectable } from "@nestjs/common";
import {
ExecutionContext,
ForbiddenException,
Injectable,
UnauthorizedException,
} from "@nestjs/common";
import { Reflector } from "@nestjs/core";
import { AuthGuard } from "@nestjs/passport";
import { IS_PUBLIC_PATH } from "src/utils/decorators/auth.decorator";
import { AuthorizedUser } from "src/utils/types/req.type";

@Injectable()
export class JwtAuthGuard extends AuthGuard("jwt") {
Expand All @@ -19,4 +25,17 @@ export class JwtAuthGuard extends AuthGuard("jwt") {
}
return super.canActivate(context);
}

handleRequest<User = AuthorizedUser>(err: Error, user: User, info: Error): User {
if (err || !user) {
if (info?.name === "TokenExpiredError") {
throw new UnauthorizedException("Token has expired.");
} else if (info?.name === "JsonWebTokenError") {
throw new UnauthorizedException("Invalid token");
} else {
throw err || new ForbiddenException("Access denied");
}
}
return user;
}
}
2 changes: 1 addition & 1 deletion backend/src/documents/documents.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export class DocumentsService {
},
});
} catch (e) {
throw new NotFoundException();
throw new NotFoundException("Document not found");
}

return {
Expand Down
6 changes: 3 additions & 3 deletions backend/src/files/files.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,11 @@ export class FilesService {
},
});
} catch (e) {
throw new UnauthorizedException();
throw new UnauthorizedException("Client unauthorized.");
}

if (contentLength > 10_000_000) {
throw new UnprocessableEntityException();
throw new UnprocessableEntityException("Content length too long.");
}

const fileKey = `${workspace.slug}-${generateRandomKey()}.${contentType.split("/")[1]}`;
Expand All @@ -75,7 +75,7 @@ export class FilesService {
});
return getSignedUrl(this.s3Client, command, { expiresIn: 3600 });
} catch (e) {
throw new NotFoundException();
throw new NotFoundException("File not found.");
}
}

Expand Down
2 changes: 1 addition & 1 deletion backend/src/intelligence/intelligence.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export class IntelligenceService {
};
const selectedPrompt = promptTemplates[feature];

if (!selectedPrompt) throw new NotFoundException();
if (!selectedPrompt) throw new NotFoundException("Feature not found");

return selectedPrompt;
}
Expand Down
2 changes: 1 addition & 1 deletion backend/src/users/users.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export class UsersService {
const { conflict } = await this.checkService.checkNameConflict(nickname);

if (conflict) {
throw new ConflictException();
throw new ConflictException("The nickname conflicts.");
}

await this.prismaService.user.update({
Expand Down
20 changes: 14 additions & 6 deletions backend/src/workspace-documents/workspace-documents.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ export class WorkspaceDocumentsService {
},
});
} catch (e) {
throw new NotFoundException();
throw new NotFoundException(
"The workspace does not exist, or the user lacks the appropriate permissions."
);
}

return this.prismaService.document.create({
Expand All @@ -52,7 +54,9 @@ export class WorkspaceDocumentsService {
},
});
} catch (e) {
throw new NotFoundException();
throw new NotFoundException(
"The workspace does not exist, or the user lacks the appropriate permissions."
);
}

const additionalOptions: Prisma.DocumentFindManyArgs = {};
Expand Down Expand Up @@ -111,14 +115,16 @@ export class WorkspaceDocumentsService {
workspaceId,
},
});

return this.prismaService.document.findUniqueOrThrow({
const document = await this.prismaService.document.findUniqueOrThrow({
where: {
id: documentId,
},
});
return document;
} catch (e) {
throw new NotFoundException();
throw new NotFoundException(
"The workspace or document does not exist, or the user lacks the appropriate permissions."
);
}
}

Expand Down Expand Up @@ -146,7 +152,9 @@ export class WorkspaceDocumentsService {
},
});
} catch (e) {
throw new NotFoundException();
throw new NotFoundException(
"The workspace or document does not exist, or the user lacks the appropriate permissions."
);
}

const token = generateRandomKey();
Expand Down
4 changes: 3 additions & 1 deletion backend/src/workspace-users/workspace-users.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ export class WorkspaceUsersService {
},
});
} catch (e) {
throw new NotFoundException();
throw new NotFoundException(
"The workspace does not exist, or the user lacks the appropriate permissions."
);
}

const additionalOptions: Prisma.UserFindManyArgs = {};
Expand Down
10 changes: 7 additions & 3 deletions backend/src/workspaces/workspaces.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export class WorkspacesService {
const { conflict } = await this.checkService.checkNameConflict(title);

if (conflict) {
throw new ConflictException();
throw new ConflictException("Workspace title is already in use.");
}

const workspace = await this.prismaService.workspace.create({
Expand Down Expand Up @@ -62,7 +62,9 @@ export class WorkspacesService {

return foundWorkspace;
} catch (e) {
throw new NotFoundException();
throw new NotFoundException(
"Workspace not found, or the user lacks the appropriate permissions."
);
}
}

Expand Down Expand Up @@ -113,7 +115,9 @@ export class WorkspacesService {
},
});
} catch (e) {
throw new NotFoundException();
throw new NotFoundException(
"Worksapce does not exist, or the user lacks the appropriate permissions."
);
}

const token = generateRandomKey();
Expand Down
17 changes: 15 additions & 2 deletions frontend/src/hooks/useErrorHandler.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,24 @@
import { useSnackbar } from "notistack";
import { useCallback } from "react";

interface CustomError extends Error {
response?: {
data: {
error: string;
message?: string;
statusCode: number;
};
};
}

export function useErrorHandler() {
const { enqueueSnackbar } = useSnackbar();
const handleError = useCallback(
(error: Error) => {
enqueueSnackbar(error.message || "Something went wrong...", { variant: "error" });
(error: CustomError) => {
enqueueSnackbar(
error.response?.data.message || error.message || "Something went wrong...",
{ variant: "error" }
);
},
[enqueueSnackbar]
);
Expand Down

0 comments on commit 6b26087

Please sign in to comment.