Giter Site home page Giter Site logo

Comments (3)

H0llyW00dzZ avatar H0llyW00dzZ commented on June 26, 2024

Note

Additionally, it should be noted that these methods are compatible with the latest version of Go (I'm using) and provide a more straightforward integration with databases.

Example:

  		Prefix: "/gopher",
  		Routes: []APIRoute{
  			{Path: "/reload", Method: fiber.MethodPost, Handler: func(c *fiber.Ctx) error { return users.ReloadConfigHandler(c, db) }},
  		},

then it will be https://go.dev/v1/gopher/reload (example)

from go-blueprint.

H0llyW00dzZ avatar H0llyW00dzZ commented on June 26, 2024

Updated:

The helper functions for these methods that can be used for custom error handling independently to avoid conflicts:

// isVersionedAPIRoute checks if the given path matches a versioned API route.
func isVersionedAPIRoute(path string) bool {
    // Define the versioned API route prefixes
    versionedAPIPrefixes := []string{"/v1", "/v2"}

    // Check if the path starts with any of the versioned API prefixes
    for _, prefix := range versionedAPIPrefixes {
        if len(path) >= len(prefix) && path[:len(prefix)] == prefix {
            return true
        }
    }

    return false
}

// apiInternalServerErrorHandler is a custom error handler for internal server errors in versioned APIs.
func apiInternalServerErrorHandler(c *fiber.Ctx, err error) error {
    // Log the error
    Logger.LogErrorf("Internal Server Error occurred in versioned API: %v", err)
    // Return a JSON response with the 500 Internal Server Error status code
    return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
        "error": fiber.ErrInternalServerError.Message,
    })
}

// apiErrorHandler is a custom error handler for versioned APIs.
// It returns JSON responses for 404 (Not Found) and 403 (Forbidden) status codes.
func apiErrorHandler(c *fiber.Ctx) error {
    // Check if the response status code is already set
    if c.Response().StatusCode() != fiber.StatusOK {
        // Get the current status code
        statusCode := c.Response().StatusCode()

        // Check if the status code is 404 or 403
        if statusCode == fiber.StatusNotFound {
            // Return a JSON response for 404 (Not Found) error
            return c.Status(statusCode).JSON(fiber.Map{
                "error": fiber.ErrNotFound.Message,
            })
        } else if statusCode == fiber.StatusForbidden {
            // Return a JSON response for 403 (Forbidden) error
            return c.Status(statusCode).JSON(fiber.Map{
                "error": fiber.ErrForbidden.Message,
            })
        }
    }

    // If the status code is not 404 or 403, continue with the original request
    return c.Next()
}

Then, you can simplify and call them like this:

    // Set custom error handler for the application
    app.Use(func(c *fiber.Ctx) error {
        // Call the next route handler and catch any errors
        err := c.Next()

        // If there was an error, use the custom error handler
        if err != nil {
            // Check if the error is a 404 or 403 error for versioned APIs
            if e, ok := err.(*fiber.Error); ok {
                if e.Code == fiber.StatusNotFound || e.Code == fiber.StatusForbidden {
                    // Check if the request path matches a versioned API route
                    if isVersionedAPIRoute(c.Path()) {
                        // Return a JSON response for 404 or 403 errors in versioned APIs
                        return c.Status(e.Code).JSON(fiber.Map{
                            "error": e.Message,
                        })
                    }
                }
            }

            // Check if the error is a 404 or 403 error for frontend routes
            if e, ok := err.(*fiber.Error); ok {
                if e.Code == fiber.StatusNotFound {
                    // Check if the request path matches a frontend route
                    if isFrontendRoute(c.Path()) {
                        // Render the 404 error page for frontend routes
                        return webPageHandler.PageNotFoundHandler(c)
                    }
                } else if e.Code == fiber.StatusForbidden {
                    // Check if the request path matches a frontend route
                    if isFrontendRoute(c.Path()) {
                        // Render the 403 error page for frontend routes
                        return webPageHandler.PageForbidden403Handler(c)
                    }
                }
            }

            // If the error is not a 404 or 403 error for versioned APIs or frontend routes, check if it's an internal server error
            if e, ok := err.(*fiber.Error); ok && e.Code == fiber.StatusInternalServerError {
                // Return a JSON response for internal server errors in versioned APIs
                return apiInternalServerErrorHandler(c, err)
            }

            // If the error is not a versioned API error, frontend error, or internal server error, fallback to the general error page
            return webPageHandler.Page500InternalServerHandler(c, err)
        }

        // ... rest of the code ...
    })

When a versioned API route is not found, it will use the original message provided by the Fiber framework, as it is reusable.
Example:

image

Note

Also note that Page500InternalServerHandler and apiInternalServerErrorHandler are for handling manipulate panics.

from go-blueprint.

briancbarrow avatar briancbarrow commented on June 26, 2024

Like we mentioned in the other issues/PRs, versioning is something that can be handled by each user as they see fit.

from go-blueprint.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.