HTTP errors!
This commit is contained in:
parent
194fa476ca
commit
f1c4fbdb95
5
TODO.txt
5
TODO.txt
@ -22,3 +22,8 @@ unit tests
|
||||
integration tests
|
||||
documentation & docs site
|
||||
events and observables?
|
||||
no matching route handler
|
||||
request timeout
|
||||
not handlers -> not implemented
|
||||
method not allowed
|
||||
error response handler figure out json
|
||||
|
@ -1,6 +1,6 @@
|
||||
import Controller from '../../../lib/src/http/Controller.ts'
|
||||
import {Request} from '../../../lib/src/http/Request.ts'
|
||||
import {error, html, redirect} from '../../../lib/src/http/response/helpers.ts'
|
||||
import {error, html, http, redirect} from '../../../lib/src/http/response/helpers.ts'
|
||||
|
||||
export default class TestController extends Controller {
|
||||
|
||||
@ -9,10 +9,10 @@ export default class TestController extends Controller {
|
||||
}
|
||||
|
||||
get_user_home(request: Request) {
|
||||
return redirect('/home')
|
||||
return http(401, 'You should not be here!')
|
||||
}
|
||||
|
||||
create_user_home(request: Request) {
|
||||
return error('Not implemented!')
|
||||
return http(401)
|
||||
}
|
||||
}
|
||||
|
168
lib/src/const/http.ts
Normal file
168
lib/src/const/http.ts
Normal file
@ -0,0 +1,168 @@
|
||||
export enum HTTPStatus {
|
||||
http100 = 100,
|
||||
http101 = 101,
|
||||
http102 = 102,
|
||||
http200 = 200,
|
||||
http201 = 201,
|
||||
http202 = 202,
|
||||
http203 = 203,
|
||||
http204 = 204,
|
||||
http205 = 205,
|
||||
http206 = 206,
|
||||
http207 = 207,
|
||||
http300 = 300,
|
||||
http301 = 301,
|
||||
http302 = 302,
|
||||
http303 = 303,
|
||||
http304 = 304,
|
||||
http305 = 305,
|
||||
http307 = 307,
|
||||
http308 = 308,
|
||||
http400 = 400,
|
||||
http401 = 401,
|
||||
http402 = 402,
|
||||
http403 = 403,
|
||||
http404 = 404,
|
||||
http405 = 405,
|
||||
http406 = 406,
|
||||
http407 = 407,
|
||||
http408 = 408,
|
||||
http409 = 409,
|
||||
http410 = 410,
|
||||
http411 = 411,
|
||||
http412 = 412,
|
||||
http413 = 413,
|
||||
http414 = 414,
|
||||
http415 = 415,
|
||||
http416 = 416,
|
||||
http417 = 417,
|
||||
http418 = 418,
|
||||
http419 = 419,
|
||||
http420 = 420,
|
||||
http422 = 422,
|
||||
http423 = 423,
|
||||
http424 = 424,
|
||||
http428 = 428,
|
||||
http429 = 429,
|
||||
http431 = 431,
|
||||
http500 = 500,
|
||||
http501 = 501,
|
||||
http502 = 502,
|
||||
http503 = 503,
|
||||
http504 = 504,
|
||||
http505 = 505,
|
||||
http507 = 507,
|
||||
http511 = 511,
|
||||
|
||||
CONTINUE = 100,
|
||||
SWITCHING_PROTOCOLS = 101,
|
||||
PROCESSING = 102,
|
||||
OK = 200,
|
||||
CREATED = 201,
|
||||
ACCEPTED = 202,
|
||||
NON_AUTHORITATIVE_INFORMATION = 203,
|
||||
NO_CONTENT = 204,
|
||||
RESET_CONTENT = 205,
|
||||
PARTIAL_CONTENT = 206,
|
||||
MULTI_STATUS = 207,
|
||||
MULTIPLE_CHOICES = 300,
|
||||
MOVED_PERMANENTLY = 301,
|
||||
MOVED_TEMPORARILY = 302,
|
||||
SEE_OTHER = 303,
|
||||
NOT_MODIFIED = 304,
|
||||
USE_PROXY = 305,
|
||||
TEMPORARY_REDIRECT = 307,
|
||||
PERMANENT_REDIRECT = 308,
|
||||
BAD_REQUEST = 400,
|
||||
UNAUTHORIZED = 401,
|
||||
PAYMENT_REQUIRED = 402,
|
||||
FORBIDDEN = 403,
|
||||
NOT_FOUND = 404,
|
||||
METHOD_NOT_ALLOWED = 405,
|
||||
NOT_ACCEPTABLE = 406,
|
||||
PROXY_AUTHENTICATION_REQUIRED = 407,
|
||||
REQUEST_TIMEOUT = 408,
|
||||
CONFLICT = 409,
|
||||
GONE = 410,
|
||||
LENGTH_REQUIRED = 411,
|
||||
PRECONDITION_FAILED = 412,
|
||||
REQUEST_TOO_LONG = 413,
|
||||
REQUEST_URI_TOO_LONG = 414,
|
||||
UNSUPPORTED_MEDIA_TYPE = 415,
|
||||
REQUESTED_RANGE_NOT_SATISFIABLE = 416,
|
||||
EXPECTATION_FAILED = 417,
|
||||
IM_A_TEAPOT = 418,
|
||||
INSUFFICIENT_SPACE_ON_RESOURCE = 419,
|
||||
METHOD_FAILURE = 420,
|
||||
UNPROCESSABLE_ENTITY = 422,
|
||||
LOCKED = 423,
|
||||
FAILED_DEPENDENCY = 424,
|
||||
PRECONDITION_REQUIRED = 428,
|
||||
TOO_MANY_REQUESTS = 429,
|
||||
REQUEST_HEADER_FIELDS_TOO_LARGE = 431,
|
||||
INTERNAL_SERVER_ERROR = 500,
|
||||
NOT_IMPLEMENTED = 501,
|
||||
BAD_GATEWAY = 502,
|
||||
SERVICE_UNAVAILABLE = 503,
|
||||
GATEWAY_TIMEOUT = 504,
|
||||
HTTP_VERSION_NOT_SUPPORTED = 505,
|
||||
INSUFFICIENT_STORAGE = 507,
|
||||
NETWORK_AUTHENTICATION_REQUIRED = 511,
|
||||
}
|
||||
|
||||
export const Message = {
|
||||
100: 'Continue',
|
||||
101: 'Switching Protocols',
|
||||
102: 'Processing',
|
||||
200: 'OK',
|
||||
201: 'Created',
|
||||
202: 'Accepted',
|
||||
203: 'Non Authoritative Information',
|
||||
204: 'No Content',
|
||||
205: 'Reset Content',
|
||||
206: 'Partial Content',
|
||||
207: 'Multi-Status',
|
||||
300: 'Multiple Choices',
|
||||
301: 'Moved Permanently',
|
||||
302: 'Moved Temporarily',
|
||||
303: 'See Other',
|
||||
304: 'Not Modified',
|
||||
305: 'Use Proxy',
|
||||
307: 'Temporary Redirect',
|
||||
308: 'Permanent Redirect',
|
||||
400: 'Bad Request',
|
||||
401: 'Unauthorized',
|
||||
402: 'Payment Required',
|
||||
403: 'Forbidden',
|
||||
404: 'Not Found',
|
||||
405: 'Method Not Allowed',
|
||||
406: 'Not Acceptable',
|
||||
407: 'Proxy Authentication Required',
|
||||
408: 'Request Timeout',
|
||||
409: 'Conflict',
|
||||
410: 'Gone',
|
||||
411: 'Length Required',
|
||||
412: 'Precondition Failed',
|
||||
413: 'Request Entity Too Large',
|
||||
414: 'Request-URI Too Long',
|
||||
415: 'Unsupported Media Type',
|
||||
416: 'Request Range Not Satisfiable',
|
||||
417: 'Expectation Failed',
|
||||
418: 'I\'m a teapot',
|
||||
419: 'Insufficient Space on Resource',
|
||||
420: 'Method Failure',
|
||||
422: 'Unprocessable Entity',
|
||||
423: 'Locked',
|
||||
424: 'Failed Dependency',
|
||||
428: 'Precondition Required',
|
||||
429: 'Too Many Requests',
|
||||
431: 'Request Header Fields Too Large',
|
||||
500: 'Server Error',
|
||||
501: 'Not Implemented',
|
||||
502: 'Bad Gateway',
|
||||
503: 'Service Unavailable',
|
||||
504: 'Gateway Timeout',
|
||||
505: 'HTTP Version Not Supported',
|
||||
507: 'Insufficient Storage',
|
||||
511: 'Network Authentication Required',
|
||||
}
|
10
lib/src/error/HTTPError.ts
Normal file
10
lib/src/error/HTTPError.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import {HTTPStatus, Message} from '../const/http.ts'
|
||||
|
||||
export default class HTTPError extends Error {
|
||||
constructor(
|
||||
public readonly http_status: HTTPStatus,
|
||||
public readonly http_message?: string
|
||||
) {
|
||||
super(`HTTP ${http_status}: ${http_message || Message[http_status]}`)
|
||||
}
|
||||
}
|
@ -1,13 +1,14 @@
|
||||
import ResponseFactory from './ResponseFactory.ts'
|
||||
import {Request} from '../Request.ts'
|
||||
import * as api from '../../support/api.ts'
|
||||
import {HTTPStatus} from '../../const/http.ts'
|
||||
|
||||
export default class ErrorResponseFactory extends ResponseFactory {
|
||||
protected target_mode: 'json' | 'html' = 'html'
|
||||
|
||||
constructor(
|
||||
public readonly error: Error,
|
||||
status: number = 500,
|
||||
status: HTTPStatus = HTTPStatus.INTERNAL_SERVER_ERROR,
|
||||
output: 'json' | 'html' = 'html',
|
||||
) {
|
||||
super()
|
||||
|
11
lib/src/http/response/HTTPErrorResponseFactory.ts
Normal file
11
lib/src/http/response/HTTPErrorResponseFactory.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import ErrorResponseFactory from './ErrorResponseFactory.ts'
|
||||
import HTTPError from '../../error/HTTPError.ts'
|
||||
|
||||
export default class HTTPErrorResponseFactory extends ErrorResponseFactory {
|
||||
constructor(
|
||||
public readonly error: HTTPError,
|
||||
output: 'json' | 'html',
|
||||
) {
|
||||
super(error, error.http_status, output)
|
||||
}
|
||||
}
|
@ -1,15 +1,16 @@
|
||||
import AppClass from '../../lifecycle/AppClass.ts'
|
||||
import {Request} from '../Request.ts'
|
||||
import {HTTPStatus} from '../../const/http.ts'
|
||||
|
||||
export default abstract class ResponseFactory extends AppClass {
|
||||
protected target_status: number = 200
|
||||
protected target_status: HTTPStatus = HTTPStatus.OK
|
||||
|
||||
public async write(request: Request): Promise<Request> {
|
||||
request.response.status = this.target_status
|
||||
return request
|
||||
}
|
||||
|
||||
public status(status: number): ResponseFactory {
|
||||
public status(status: HTTPStatus): ResponseFactory {
|
||||
this.target_status = status
|
||||
return this
|
||||
}
|
||||
|
@ -1,8 +1,9 @@
|
||||
import ResponseFactory from './ResponseFactory.ts'
|
||||
import {Request} from '../Request.ts'
|
||||
import {HTTPStatus} from '../../const/http.ts'
|
||||
|
||||
export default class TemporaryRedirectResponseFactory extends ResponseFactory {
|
||||
protected target_status: number = 302
|
||||
protected target_status: HTTPStatus = HTTPStatus.TEMPORARY_REDIRECT
|
||||
|
||||
constructor(
|
||||
public readonly destination: string,
|
||||
|
@ -5,6 +5,9 @@ import ErrorResponseFactory from './ErrorResponseFactory.ts'
|
||||
import {Rehydratable} from '../../support/Rehydratable.ts'
|
||||
import DehydratedStateResponseFactory from './DehydratedStateResponseFactory.ts'
|
||||
import TemporaryRedirectResponseFactory from './TemporaryRedirectResponseFactory.ts'
|
||||
import {HTTPStatus} from "../../const/http.ts";
|
||||
import HTTPErrorResponseFactory from "./HTTPErrorResponseFactory.ts";
|
||||
import HTTPError from "../../error/HTTPError.ts";
|
||||
|
||||
export function json(value: any): JSONResponseFactory {
|
||||
return make(JSONResponseFactory, value)
|
||||
@ -26,3 +29,7 @@ export function dehydrate(value: Rehydratable): DehydratedStateResponseFactory {
|
||||
export function redirect(destination: string): TemporaryRedirectResponseFactory {
|
||||
return make(TemporaryRedirectResponseFactory, destination)
|
||||
}
|
||||
|
||||
export function http(status: HTTPStatus, message?: string) {
|
||||
return make(HTTPErrorResponseFactory, new HTTPError(status, message))
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user