-
Notifications
You must be signed in to change notification settings - Fork 87
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactor: migrate errors server controller to typescript #327
Conversation
b68ac0b
to
0001393
Compare
0001393
to
ac523e5
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some changes requested, with the main one being to change it to a pure utility file.
Please try to think of ways to improve the code too when you are refactoring instead of plainly converting JS to TS code! The main point we are doing this is to reduce tech debt/legacy code after all :D
@@ -1,39 +1,41 @@ | |||
'use strict' | |||
import _ from 'lodash' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: prefer explicit destructure of used imports:
// If only one is being used.
import isEmpty from 'lodash/isEmpty'
// If multiple lodash functions are being used in this file
import { isEmpty, somethingElse } from 'lodash'
|
||
/** | ||
* Private helper for getMongoErrorMessage to return Mongo error in a String | ||
* @param {Object} err - MongoDB error object | ||
* @param {IMongoError} err - MongoDB error object |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Remove types from JSDocs, it's already typed in the function signature
|
||
/** | ||
* Default error message if no more specific error | ||
* @type {String} | ||
*/ | ||
exports.defaultErrorMessage = 'An unexpected error happened. Please try again.' | ||
export const defaultErrorMessage = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At first glance, I thought this is only used in one place, but seems to also be used in tests. Add a comment stating this is also exported for tests? Though I don't actually think it's necessary, we can also just hardcode this string in the tests.
If you still want to export it, constants should be named in UPPER_SNAKE_CASE for consistency.
export const defaultErrorMessage = | |
export const DEFAULT_ERROR_MSG = |
* @return {String} errorString - Formatted error string | ||
*/ | ||
const mongoDuplicateKeyError = function (err) { | ||
|
||
const mongoDuplicateKeyError = function (err: IMongoError): string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a fan of this function, I think it is too hackish instead of fixing the base issue.
In fact, in the entire schema, there is only one instance of a schema with a unique
parameter, i.e UserModel
, and that case is already handled by it's own post-validation hook. Meaning we do not even need this function and this function can be deleted
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can also keep it in if you want, but I'm not a fan of this weird error message interpolation.
@@ -1,39 +1,41 @@ | |||
'use strict' | |||
import _ from 'lodash' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please update all functions that do not need the this
parameter (which is all of the functions in this file) into arrow functions.
See further reading for differences between arrow functions and regular functions
@@ -1,39 +1,41 @@ | |||
'use strict' | |||
import _ from 'lodash' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should also move and rename this file to the utility function it is, probably into utils/handleMongoError.ts
Read more about utility vs service functions/classes here, and read more about the differences between service and controllers layers (this is more Java-like but the point still stands) to see why the functions in this file does not belong in the controller layer. Do hit me (or Google) up for a more detailed explanation if you still have any queries
* @return {String} message - Error message returned to frontend | ||
*/ | ||
exports.getMongoErrorMessage = function (err) { | ||
export function getMongoErrorMessage(err?: IMongoError | string): string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This whole function seems like it needs a good refactor, maybe we should try to clean up the function?
I don't think we should create the IMongoError
interface when we already have the typings of the possible errors:
import { MongoError } from 'mongodb'
import { Error as MongooseError } from 'mongoose'
...
export const getMongoErrorMessage = (
err?: MongoError | MongooseError | string,
): string => { ... }
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggested refactor:
export const getMongoErrorMessage = (
err?: MongoError | MongooseError | string,
): string => {
if (!err) {
return ''
}
// Handle base Mongo engine errors.
if (err instanceof MongoError) {
switch (err.code) {
case 10334: // BSONObj size invalid error
return 'Your form is too large to be supported by the system.'
default:
return defaultErrorMessage
}
}
// Handle mongoose errors.
if (err instanceof MongooseError.ValidationError) {
// Join all error messages into a single message if available.
const joinedMessage = Object.values(err.errors)
.map((err) => err.message)
.join(', ')
return joinedMessage ?? err.message ?? defaultErrorMessage
}
if (err instanceof MongooseError) {
return err.message ?? defaultErrorMessage
}
return err ?? defaultErrorMessage
}
@@ -0,0 +1,11 @@ | |||
export interface IMongoError { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unneeded, as explained above
@@ -1,65 +1,62 @@ | |||
describe('Errors Controller', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remember to update tests
Any updates on this PR? |
Closing first to deprioritise, will pick up again after helium |
Part of #144