Skip to content
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

Closed
wants to merge 6 commits into from

Conversation

tshuli
Copy link
Contributor

@tshuli tshuli commented Sep 17, 2020

Part of #144

@tshuli tshuli force-pushed the refactor/errors-server-controller branch from b68ac0b to 0001393 Compare September 17, 2020 06:23
@tshuli tshuli force-pushed the refactor/errors-server-controller branch from 0001393 to ac523e5 Compare September 17, 2020 06:24
@tshuli tshuli changed the title wip: Refactor/errors server controller Refactor/errors server controller Sep 17, 2020
@tshuli tshuli marked this pull request as ready for review September 17, 2020 06:42
@tshuli tshuli changed the title Refactor/errors server controller refactor: migrate errors server controller to typescript Sep 17, 2020
Copy link
Contributor

@karrui karrui left a 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'
Copy link
Contributor

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
Copy link
Contributor

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 =
Copy link
Contributor

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.

Suggested change
export const defaultErrorMessage =
export const DEFAULT_ERROR_MSG =

* @return {String} errorString - Formatted error string
*/
const mongoDuplicateKeyError = function (err) {

const mongoDuplicateKeyError = function (err: IMongoError): string {
Copy link
Contributor

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

Copy link
Contributor

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'
Copy link
Contributor

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'
Copy link
Contributor

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 {
Copy link
Contributor

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 => { ... }

Copy link
Contributor

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 {
Copy link
Contributor

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', () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remember to update tests

@karrui
Copy link
Contributor

karrui commented Oct 5, 2020

Any updates on this PR?

@tshuli
Copy link
Contributor Author

tshuli commented Oct 9, 2020

Closing first to deprioritise, will pick up again after helium

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants