-
Notifications
You must be signed in to change notification settings - Fork 66
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
Rethink/Reorganise HTTP error structure #4101
Rethink/Reorganise HTTP error structure #4101
Comments
Also this means if someone returns an |
We decided to move these HTTP status code errors to In addition, following is an example of public type User record {|
string id;
string name;
|};
public type MyErrorPayload record {|
time:Utc timeStamp;
string message;
string details;
|};
public type MyDetaultErrorDetail record {
*HttpDefaultErrorDetail;
MyErrorPayload body;
};
type MyHttpDefaultStatusCodeError HttpDefaultStatusCodeError & error<MyDetaultErrorDetail>;
service /dept on new http:Listener(9090) {
resource function get user/[string id]() returns User|MyHttpDefaultStatusCodeError {
do {
return check getUserName(id);
} on fail error err {
MyDetaultErrorDetail errDetails = {
timeStamp: time:utcNow(),
message: "User not found",
details: string `/dept/user/${id}`
};
return error MyHttpDefaultStatusCodeError("Error occurred while processing the request", err, body = errDetails);
}
}
}
function getUserName(string id) returns User|UserNotFoundError {
if (id == "1") {
return {id: "1", name: "John"};
} else {
return error UserNotFoundError("User not found");
}
}
type UserNotFoundError error & HttpNotFoundError;
|
Following is how OpenAPI looks like for the above code. openapi: 3.0.1
info:
title: Dept
version: 0.0.0
servers:
- url: "{server}:{port}/dept"
variables:
server:
default: http://localhost
port:
default: "9090"
paths:
/user/{id}:
get:
operationId: getUserId
parameters:
- name: id
in: path
required: true
schema:
type: string
responses:
"200":
description: Ok
content:
application/json:
schema:
$ref: '#/components/schemas/User'
"default":
description: Default error for user API
content:
application/json:
schema:
$ref: '#/components/schemas/MyDetaultErrorDetail'
components:
schemas:
User:
required:
- id
- name
type: object
properties:
id:
type: string
name:
type: string
MyDetaultErrorDetail:
required:
- message
- details
type: object
properties:
code:
type: string
message:
type: string |
In cases where errors are originated from libraries, the code would like the below. service /dept on new http:Listener(9090) {
resource function get user/[string id]() returns User|MyHttpDefaultStatusCodeError {
do {
string validId = check constraint:validate(id);
return check getUserName(validId);
} on fail error err {
MyErrorPayload errDetails = {
timeStamp: time:utcNow(),
message: "User not found",
details: string `/dept/user/${id}`
};
if err is constraint:Error {
return error MyHttpDefaultStatusCodeError("Error occurred while processing the request", err, body = errDetails, statusCode = 400);
}
return error MyHttpDefaultStatusCodeError("Error occurred while processing the request", err, body = errDetails);
}
}
} |
Current code would look like this. service /dept on new http:Listener(9090) {
resource function get user/[string id]() returns User|MyUserNotFound|MyBadRequest|MyInternelServerError {
do {
string validId = check constraint:validate(id);
return check getUserName(validId);
} on fail error err {
MyErrorPayload errDetails = {
timeStamp: time:utcNow(),
message: "User not found",
details: string `/dept/user/${id}`
};
if err is constraint:Error {
return <MyBadRequest>{body: errDetails};
} else if err is UserNotFoundError {
return <MyUserNotFound>{body: errDetails};
} else {
return <MyInternelServerError>{body: errDetails};
}
}
}
}
type UserNotFoundError distinct error;
function getUserName(string id) returns User|error {
if (id == "1") {
return {id: "1", name: "John"};
} else {
return error ("User not found");
}
} |
Model of the HTTP error handling hierarchy is something like the below.
Usual purpose of these errors is to represent expected but undesirable results of functions. Usual actions of these error messages are,
In the case of the HTTP module, there is this ADDITIONAL requirement to send a HTTP response when these errors propagate to the listener. These responses attributes such as,
To cater to this additional requirement we can model a parallel error structure as follows.
Then we can connect to two models as follows,
Here the
default
error is the error used to represent all the errors. It is similar to switch-case-default relationship. See this for more details.https://swagger.io/docs/specification/describing-responses/
Following is the sample code.
The text was updated successfully, but these errors were encountered: