Errors
The Actions use the same error mechanism as any other Go function.
When an Action returns an error, its execution ends immediately and the client receives the error as the second element of the result.
There is no need to build error responses manually.
Return an error
An Action can return any value that implements the interface error.
func Login() gox.Action {
return errors.New("Invalid credentials")
} const [result, err] = await Actions.Login()
console.log(result)
// null
console.log(err)
// GoxActionError When an Action returns an error, the return value will always be null.
Errors during execution
It is common to return errors produced by other functions.
func GetUser(id string) gox.Action {
user, err := database.FindUser(id)
if err != nil {
return err
}
return user
} It is not necessary to transform the error before returning it.
However, before returning an external error directly, it must be checked that your message is safe for the client.
Create Errors
Errors can be created using any usual Go mechanism.
return errors.New("Access denied") It is also possible to return errors built with additional information.
return fmt.Errorf(
"User %s not found",
id,
) GOX does not impose a specific type to represent errors.
When sending it to the client, GOX uses the text produced by the method Error().
Client
The Actions always return a tupla.
const [user, err] = await Actions.GetUser(id) When the Action completes successfully:
user !== null
err === null When a mistake occurs:
user === null
err instanceof Error The errors of the Actions are instances of GoxActionError, a type that extends the native object Error.
const [user, err] =
await Actions.GetUser(id)
if (err) {
console.log(err.name)
// GoxActionError
console.log(err.message)
// User not found
console.log(err.type)
// ACTION_ERROR
console.log(err.action)
// GetUser
return
}
console.log(user.name) It is advisable to check first if there is an error before using the result.
Error information
An instance of GoxActionError may contain the following properties:
| Property | Description |
|---|---|
message | Message received from the server or generated by the client |
name | Error name: GoxActionError |
code | Numeric error code |
type | Identifiable type of error |
action | Name of the Action invoked |
status | Associated HTTP State |
cause | Original error when generated in the client |
The errors returned directly by an Action use the type ACTION_ERROR.
if (err?.type === "ACTION_ERROR") {
console.error(err.message)
} GOX transmits the error message, but does not reconstruct in JavaScript the custom type used in Go or expose the server stack.
Propagation of errors
As the Actions use conventional Go errors, they can be spread using the usual language patterns.
user, err := repository.FindUser(id)
if err != nil {
return err
} This allows for the re-use of existing libraries and functions without modification.
Before spreading an error to the client it should be verified that it does not disclose internal information of the application.
When the error contains sensitive details, it is preferable to register it on the server and return a controlled message.
user, err := repository.FindUser(id)
if err != nil {
log.Printf("failed to find user %q: %v", id, err)
return errors.New("Unable to retrieve the user")
} Client errors
GoxActionError It also represents errors that can occur before the Action ends properly.
These include:
- Undefined actions.
- Invalid arguments.
- Network errors.
- Methods not allowed.
- Invalid responses.
- Uncompatible types of response.
- Internal server errors.
Property type allows them to be distinguished.
const [result, err] =
await Actions.SaveUser(user)
if (err?.type === "NETWORK_ERROR") {
console.log("Unable to connect to the server")
} Panics
When a panic, GOX interrupts the request and responds with an internal server error.
func CreateReport() gox.Action {
panic("report generator failed")
} The client receives a GoxActionError of the type SERVER_ERROR.
const [report, err] =
await Actions.CreateReport()
console.log(report)
// null
console.log(err.type)
// SERVER_ERROR
console.log(err.status)
// 500 The internal message of the panic it is not delivered to the client.
GOX records the error on the server, where it can keep useful information to diagnose the problem without publicly exposing it.
The panic should be reserved for unexpected situations. The expected errors should be returned using values error.
Security
Returning errors directly is practical, but you can also reveal information about the internal functioning of the server.
Errors produced by databases, file systems, external services or bookstores may contain:
- Internal routes.
- Consultations or table names.
- Service addresses.
- Private identifiers.
- Configuration details.
- Useful information for infrastructure analysis.
Before returning an error it must be verified that your message is appropriate for the client, especially when the error was not created directly by the application.
When it is necessary to keep the original error, you can register on the server and return a controlled message to the client.
Best practices
- Returns errors as soon as they are detected.
- It uses clear and descriptive messages.
- Always check if there is an error before using the result of an Action.
- Check that the message is safe before you directly return an error.
- It pays particular attention to errors from bookstores, databases and external services.
- It records the internal details on the server and returns controlled messages to the client.
- Do not depend on custom Go error types in JavaScript, as only the message is transmitted.
- Use
paniconly for unexpected situations. - Avoid using errors to control the normal flow of the application.
To learn more about ActionsSee your documentation. To learn more about ParametersSee your documentation. To learn more about FormsSee your documentation. To learn more about Return Values, check your documentation.