Skip to main content

Coding Standards

Branching and PRs

  • Make sure you branch off of staging.
  • Name your branches as eng-<linear ticket number>-do-this-do-that. For example: eng-123-implement-skibidi-functionality
  • Follow the branching strategy specified in the docs: TODO
  • Once ready to make a (draft) PR
    • Title it as [<linear ticket name>] <short description>. For example: [ENG-123] Implement skibidi functionality
    • Ensure all tests are passing and let the teammates know to review it. You will need at least 1 approval.
    • Merge your branch into staging using the Squash and merge option. This will keep the commit history clean and easy to follow.
    • Delete the branch after merging.

Logging Strategy

To log, from ghost.logs import log. The imported log instance is from an inherited class of a 3rd party library called django-structlog[celery]. You can use it as you would a structlog logger. For example:

from ghost.logs import log
log.info("This is an info message", more_details="This is additional info")
log.error("This is an error message")
log.warn("This is a warning message")

You can find more documentation on the log instance at: structlog.org/en/stable/getting-started.html#your-first-log-entry

Exception Management

Exceptions signify an unexpected event. They could be fatal to our system. All exceptions should be logged and re-raised if necessary for the caller to handle.

log.error(message, ...extra_param) is to just print an error message along with extra parameters passed. Use it when you don't need to raise the exception after logging it.

log.error_and_raise(exception, ...extra_param) logs an exception and then raises/reraises it.

Pass in exc_info=exc to the log.error/log.error_and_raise method to log the exception stack trace for exc as well. Make sure you do this when available so no exception information is lost.

Exception Logging Patterns

An anamoly for the pattern is validator files responsible for strictly raising execeptions. No need to log anything there.

  1. To catch an exception, log it and then continue execution (no re-raise).

    try:
    value = 2 / 0
    except Exception as exc:
    log.error("Something went wrong during calculation", error_info="This is additional info", exc_info=exc)
    log.info("Continuing execution after exception")

    You should log.error the exception with the exc_info parameter set to the thrown exception.

  2. To log an exception and then raise it:

    log.error_and_raise(ValueError("Parameter problem"))

    You should log.error_and_raise with the exception you want to raise. This way later on, adding extra information to the exception logger function is easy.

  3. To log an exception and then reraise it with a different exception:

    try:
    value = 2 / 0
    except Exception as exc:
    log.error_and_raise(ValueError("Parameter problem"), error_info="This is additional info", exc_info=exc)

    You should log.error_and_raise with the exception you want to raise and the exc_info parameter set to the caught exception.

  4. To log an exception and then reraise the same exception:

    try:
    value = 2 / 0
    except Exception as exc:
    log.error_and_raise(exc, error_info="This is additional info")

    You should log.error_and_raise with the exception you caught.