Skip to content

Commit 8db6763

Browse files
lukewagnerelliotttpchickeyacfoltzerPiotrSikora
authored
Fill in the 'error' variant (#52)
* Fill in the 'error' variant Resolves #49 * Switch to doc comments, make all variant fields optional * Rename error to error-code, and add the http-error-code downcast * Remove http-client-error, and add specializations * Address remaining comments * Regenerate proxy.md --------- Co-authored-by: Trevor Elliott <telliott@fastly.com> Co-authored-by: Luke Wagner <mail@lukewagner.name> Co-authored-by: Pat Hickey <pat@moreproductive.org> Co-authored-by: Adam Foltzer <acfoltzer@fastly.com> Co-authored-by: Piotr Sikora <piotrsikora@google.com>
1 parent 8c70f87 commit 8db6763

File tree

3 files changed

+179
-28
lines changed

3 files changed

+179
-28
lines changed

proxy.md

Lines changed: 94 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -644,6 +644,9 @@ their headers, trailers, and bodies.</p>
644644
#### <a name="output_stream">`type output-stream`</a>
645645
[`output-stream`](#output_stream)
646646
<p>
647+
#### <a name="stream_error">`type stream-error`</a>
648+
[`error`](#error)
649+
<p>
647650
#### <a name="pollable">`type pollable`</a>
648651
[`pollable`](#pollable)
649652
<p>
@@ -670,16 +673,76 @@ their headers, trailers, and bodies.</p>
670673
<li><a name="scheme.https"><code>HTTPS</code></a></li>
671674
<li><a name="scheme.other"><code>other</code></a>: <code>string</code></li>
672675
</ul>
673-
<h4><a name="error"><code>variant error</code></a></h4>
674-
<p>TODO: perhaps better align with HTTP semantics?
675-
This type enumerates the different kinds of errors that may occur when
676-
initially returning a response.</p>
676+
<h4><a name="dns_error_payload"><code>record DNS-error-payload</code></a></h4>
677+
<p>Defines the case payload type for <code>DNS-error</code> above:</p>
678+
<h5>Record Fields</h5>
679+
<ul>
680+
<li><a name="dns_error_payload.rcode"><code>rcode</code></a>: option&lt;<code>string</code>&gt;</li>
681+
<li><a name="dns_error_payload.info_code"><code>info-code</code></a>: option&lt;<code>u16</code>&gt;</li>
682+
</ul>
683+
<h4><a name="tls_alert_received_payload"><code>record TLS-alert-received-payload</code></a></h4>
684+
<p>Defines the case payload type for <code>TLS-alert-received</code> above:</p>
685+
<h5>Record Fields</h5>
686+
<ul>
687+
<li><a name="tls_alert_received_payload.alert_id"><code>alert-id</code></a>: option&lt;<code>u8</code>&gt;</li>
688+
<li><a name="tls_alert_received_payload.alert_message"><code>alert-message</code></a>: option&lt;<code>string</code>&gt;</li>
689+
</ul>
690+
<h4><a name="field_size_payload"><code>record field-size-payload</code></a></h4>
691+
<p>Defines the case payload type for <code>HTTP-response-{header,trailer}-size</code> above:</p>
692+
<h5>Record Fields</h5>
693+
<ul>
694+
<li><a name="field_size_payload.field_name"><code>field-name</code></a>: option&lt;<code>string</code>&gt;</li>
695+
<li><a name="field_size_payload.field_size"><code>field-size</code></a>: option&lt;<code>u32</code>&gt;</li>
696+
</ul>
697+
<h4><a name="error_code"><code>variant error-code</code></a></h4>
698+
<p>These cases are inspired by the IANA HTTP Proxy Error Types:
699+
https://www.iana.org/assignments/http-proxy-status/http-proxy-status.xhtml#table-http-proxy-error-types</p>
677700
<h5>Variant Cases</h5>
678701
<ul>
679-
<li><a name="error.invalid_url"><code>invalid-url</code></a>: <code>string</code></li>
680-
<li><a name="error.timeout_error"><code>timeout-error</code></a>: <code>string</code></li>
681-
<li><a name="error.protocol_error"><code>protocol-error</code></a>: <code>string</code></li>
682-
<li><a name="error.unexpected_error"><code>unexpected-error</code></a>: <code>string</code></li>
702+
<li><a name="error_code.dns_timeout"><code>DNS-timeout</code></a></li>
703+
<li><a name="error_code.dns_error"><code>DNS-error</code></a>: <a href="#dns_error_payload"><a href="#dns_error_payload"><code>DNS-error-payload</code></a></a></li>
704+
<li><a name="error_code.destination_not_found"><code>destination-not-found</code></a></li>
705+
<li><a name="error_code.destination_unavailable"><code>destination-unavailable</code></a></li>
706+
<li><a name="error_code.destination_ip_prohibited"><code>destination-IP-prohibited</code></a></li>
707+
<li><a name="error_code.destination_ip_unroutable"><code>destination-IP-unroutable</code></a></li>
708+
<li><a name="error_code.connection_refused"><code>connection-refused</code></a></li>
709+
<li><a name="error_code.connection_terminated"><code>connection-terminated</code></a></li>
710+
<li><a name="error_code.connection_timeout"><code>connection-timeout</code></a></li>
711+
<li><a name="error_code.connection_read_timeout"><code>connection-read-timeout</code></a></li>
712+
<li><a name="error_code.connection_write_timeout"><code>connection-write-timeout</code></a></li>
713+
<li><a name="error_code.connection_limit_reached"><code>connection-limit-reached</code></a></li>
714+
<li><a name="error_code.tls_protocol_error"><code>TLS-protocol-error</code></a></li>
715+
<li><a name="error_code.tls_certificate_error"><code>TLS-certificate-error</code></a></li>
716+
<li><a name="error_code.tls_alert_received"><code>TLS-alert-received</code></a>: <a href="#tls_alert_received_payload"><a href="#tls_alert_received_payload"><code>TLS-alert-received-payload</code></a></a></li>
717+
<li><a name="error_code.http_request_denied"><code>HTTP-request-denied</code></a></li>
718+
<li><a name="error_code.http_request_length_required"><code>HTTP-request-length-required</code></a></li>
719+
<li><a name="error_code.http_request_body_size"><code>HTTP-request-body-size</code></a>: option&lt;<code>u64</code>&gt;</li>
720+
<li><a name="error_code.http_request_method_invalid"><code>HTTP-request-method-invalid</code></a></li>
721+
<li><a name="error_code.http_request_uri_invalid"><code>HTTP-request-URI-invalid</code></a></li>
722+
<li><a name="error_code.http_request_uri_too_long"><code>HTTP-request-URI-too-long</code></a></li>
723+
<li><a name="error_code.http_request_header_section_size"><code>HTTP-request-header-section-size</code></a>: option&lt;<code>u32</code>&gt;</li>
724+
<li><a name="error_code.http_request_header_size"><code>HTTP-request-header-size</code></a>: option&lt;<a href="#field_size_payload"><a href="#field_size_payload"><code>field-size-payload</code></a></a>&gt;</li>
725+
<li><a name="error_code.http_request_trailer_section_size"><code>HTTP-request-trailer-section-size</code></a>: option&lt;<code>u32</code>&gt;</li>
726+
<li><a name="error_code.http_request_trailer_size"><code>HTTP-request-trailer-size</code></a>: <a href="#field_size_payload"><a href="#field_size_payload"><code>field-size-payload</code></a></a></li>
727+
<li><a name="error_code.http_response_incomplete"><code>HTTP-response-incomplete</code></a></li>
728+
<li><a name="error_code.http_response_header_section_size"><code>HTTP-response-header-section-size</code></a>: option&lt;<code>u32</code>&gt;</li>
729+
<li><a name="error_code.http_response_header_size"><code>HTTP-response-header-size</code></a>: <a href="#field_size_payload"><a href="#field_size_payload"><code>field-size-payload</code></a></a></li>
730+
<li><a name="error_code.http_response_body_size"><code>HTTP-response-body-size</code></a>: option&lt;<code>u64</code>&gt;</li>
731+
<li><a name="error_code.http_response_trailer_section_size"><code>HTTP-response-trailer-section-size</code></a>: option&lt;<code>u32</code>&gt;</li>
732+
<li><a name="error_code.http_response_trailer_size"><code>HTTP-response-trailer-size</code></a>: <a href="#field_size_payload"><a href="#field_size_payload"><code>field-size-payload</code></a></a></li>
733+
<li><a name="error_code.http_response_transfer_coding"><code>HTTP-response-transfer-coding</code></a>: option&lt;<code>string</code>&gt;</li>
734+
<li><a name="error_code.http_response_content_coding"><code>HTTP-response-content-coding</code></a>: option&lt;<code>string</code>&gt;</li>
735+
<li><a name="error_code.http_response_timeout"><code>HTTP-response-timeout</code></a></li>
736+
<li><a name="error_code.http_upgrade_failed"><code>HTTP-upgrade-failed</code></a></li>
737+
<li><a name="error_code.http_protocol_error"><code>HTTP-protocol-error</code></a></li>
738+
<li><a name="error_code.loop_detected"><code>loop-detected</code></a></li>
739+
<li><a name="error_code.configuration_error"><code>configuration-error</code></a></li>
740+
<li><a name="error_code.internal_error"><code>internal-error</code></a>: option&lt;<code>string</code>&gt;<p>This is a catch-all error for anything that doesn't fit cleanly into a
741+
more specific case. It also includes an optional string for an
742+
unstructured description of the error. Users should not depend on the
743+
string for diagnosing errors, as it's not required to be consistent
744+
between implementations.
745+
</li>
683746
</ul>
684747
<h4><a name="header_error"><code>variant header-error</code></a></h4>
685748
<p>This type enumerates the different kinds of errors that may occur when
@@ -728,6 +791,23 @@ so they are provided as a list of bytes.
728791
<h4><a name="future_incoming_response"><code>resource future-incoming-response</code></a></h4>
729792
<hr />
730793
<h3>Functions</h3>
794+
<h4><a name="http_error_code"><code>http-error-code: func</code></a></h4>
795+
<p>Attempts to extract a http-related <a href="#error"><code>error</code></a> from the stream <a href="#error"><code>error</code></a>
796+
provided.</p>
797+
<p>Stream operations which return <a href="#stream_error.last_operation_failed"><code>stream-error::last-operation-failed</code></a> have
798+
a payload with more information about the operation that failed. This
799+
payload can be passed through to this function to see if there's
800+
http-related information about the error to return.</p>
801+
<p>Note that this function is fallible because not all stream-related errors
802+
are http-related errors.</p>
803+
<h5>Params</h5>
804+
<ul>
805+
<li><a name="http_error_code.err"><code>err</code></a>: borrow&lt;<a href="#stream_error"><a href="#stream_error"><code>stream-error</code></a></a>&gt;</li>
806+
</ul>
807+
<h5>Return values</h5>
808+
<ul>
809+
<li><a name="http_error_code.0"></a> option&lt;<a href="#error_code"><a href="#error_code"><code>error-code</code></a></a>&gt;</li>
810+
</ul>
731811
<h4><a name="constructor_fields"><code>[constructor]fields: func</code></a></h4>
732812
<p>Construct an empty HTTP Fields.</p>
733813
<h5>Return values</h5>
@@ -1118,7 +1198,7 @@ implementation determine how to respond with an HTTP error response.</p>
11181198
<h5>Params</h5>
11191199
<ul>
11201200
<li><a name="static_response_outparam.set.param"><code>param</code></a>: own&lt;<a href="#response_outparam"><a href="#response_outparam"><code>response-outparam</code></a></a>&gt;</li>
1121-
<li><a name="static_response_outparam.set.response"><code>response</code></a>: result&lt;own&lt;<a href="#outgoing_response"><a href="#outgoing_response"><code>outgoing-response</code></a></a>&gt;, <a href="#error"><a href="#error"><code>error</code></a></a>&gt;</li>
1201+
<li><a name="static_response_outparam.set.response"><code>response</code></a>: result&lt;own&lt;<a href="#outgoing_response"><a href="#outgoing_response"><code>outgoing-response</code></a></a>&gt;, <a href="#error_code"><a href="#error_code"><code>error-code</code></a></a>&gt;</li>
11221202
</ul>
11231203
<h4><a name="method_incoming_response.status"><code>[method]incoming-response.status: func</code></a></h4>
11241204
<p>Returns the status code from the incoming response.</p>
@@ -1210,7 +1290,7 @@ trailers were present in the body.</p>
12101290
</ul>
12111291
<h5>Return values</h5>
12121292
<ul>
1213-
<li><a name="method_future_trailers.get.0"></a> option&lt;result&lt;option&lt;own&lt;<a href="#trailers"><a href="#trailers"><code>trailers</code></a></a>&gt;&gt;, <a href="#error"><a href="#error"><code>error</code></a></a>&gt;&gt;</li>
1293+
<li><a name="method_future_trailers.get.0"></a> option&lt;result&lt;option&lt;own&lt;<a href="#trailers"><a href="#trailers"><code>trailers</code></a></a>&gt;&gt;, <a href="#error_code"><a href="#error_code"><code>error-code</code></a></a>&gt;&gt;</li>
12141294
</ul>
12151295
<h4><a name="constructor_outgoing_response"><code>[constructor]outgoing-response: func</code></a></h4>
12161296
<p>Construct an <a href="#outgoing_response"><code>outgoing-response</code></a>, with a default <a href="#status_code"><code>status-code</code></a> of <code>200</code>.
@@ -1331,7 +1411,7 @@ but those will be reported by the <a href="#incoming_body"><code>incoming-body</
13311411
</ul>
13321412
<h5>Return values</h5>
13331413
<ul>
1334-
<li><a name="method_future_incoming_response.get.0"></a> option&lt;result&lt;result&lt;own&lt;<a href="#incoming_response"><a href="#incoming_response"><code>incoming-response</code></a></a>&gt;, <a href="#error"><a href="#error"><code>error</code></a></a>&gt;&gt;&gt;</li>
1414+
<li><a name="method_future_incoming_response.get.0"></a> option&lt;result&lt;result&lt;own&lt;<a href="#incoming_response"><a href="#incoming_response"><code>incoming-response</code></a></a>&gt;, <a href="#error_code"><a href="#error_code"><code>error-code</code></a></a>&gt;&gt;&gt;</li>
13351415
</ul>
13361416
<h2><a name="wasi:http_outgoing_handler">Import interface wasi:http/outgoing-handler</a></h2>
13371417
<p>This interface defines a handler of outgoing HTTP Requests. It should be
@@ -1347,8 +1427,8 @@ imported by components which wish to make HTTP Requests.</p>
13471427
#### <a name="future_incoming_response">`type future-incoming-response`</a>
13481428
[`future-incoming-response`](#future_incoming_response)
13491429
<p>
1350-
#### <a name="error">`type error`</a>
1351-
[`error`](#error)
1430+
#### <a name="error_code">`type error-code`</a>
1431+
[`error-code`](#error_code)
13521432
<p>
13531433
----
13541434
<h3>Functions</h3>
@@ -1368,7 +1448,7 @@ through the <a href="#future_incoming_response"><code>future-incoming-response</
13681448
</ul>
13691449
<h5>Return values</h5>
13701450
<ul>
1371-
<li><a name="handle.0"></a> result&lt;own&lt;<a href="#future_incoming_response"><a href="#future_incoming_response"><code>future-incoming-response</code></a></a>&gt;, <a href="#error"><a href="#error"><code>error</code></a></a>&gt;</li>
1451+
<li><a name="handle.0"></a> result&lt;own&lt;<a href="#future_incoming_response"><a href="#future_incoming_response"><code>future-incoming-response</code></a></a>&gt;, <a href="#error_code"><a href="#error_code"><code>error-code</code></a></a>&gt;</li>
13721452
</ul>
13731453
<h2><a name="wasi:http_incoming_handler">Export interface wasi:http/incoming-handler</a></h2>
13741454
<hr />

wit/handler.wit

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ interface incoming-handler {
2222
/// This interface defines a handler of outgoing HTTP Requests. It should be
2323
/// imported by components which wish to make HTTP Requests.
2424
interface outgoing-handler {
25-
use types.{outgoing-request, request-options, future-incoming-response, error};
25+
use types.{
26+
outgoing-request, request-options, future-incoming-response, error-code
27+
};
2628

2729
/// This function is invoked with an outgoing HTTP Request, and it returns
2830
/// a resource `future-incoming-response` which represents an HTTP Response
@@ -37,5 +39,5 @@ interface outgoing-handler {
3739
handle: func(
3840
request: outgoing-request,
3941
options: option<request-options>
40-
) -> result<future-incoming-response, error>;
42+
) -> result<future-incoming-response, error-code>;
4143
}

wit/types.wit

Lines changed: 81 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
/// their headers, trailers, and bodies.
44
interface types {
55
use wasi:clocks/monotonic-clock.{duration};
6-
use wasi:io/streams.{input-stream, output-stream};
6+
use wasi:io/streams.{input-stream, output-stream, error as stream-error};
77
use wasi:io/poll.{pollable};
88

99
/// This type corresponds to HTTP standard Methods.
@@ -27,16 +27,85 @@ interface types {
2727
other(string)
2828
}
2929

30-
/// TODO: perhaps better align with HTTP semantics?
31-
/// This type enumerates the different kinds of errors that may occur when
32-
/// initially returning a response.
33-
variant error {
34-
invalid-url(string),
35-
timeout-error(string),
36-
protocol-error(string),
37-
unexpected-error(string)
30+
/// These cases are inspired by the IANA HTTP Proxy Error Types:
31+
/// https://www.iana.org/assignments/http-proxy-status/http-proxy-status.xhtml#table-http-proxy-error-types
32+
variant error-code {
33+
DNS-timeout,
34+
DNS-error(DNS-error-payload),
35+
destination-not-found,
36+
destination-unavailable,
37+
destination-IP-prohibited,
38+
destination-IP-unroutable,
39+
connection-refused,
40+
connection-terminated,
41+
connection-timeout,
42+
connection-read-timeout,
43+
connection-write-timeout,
44+
connection-limit-reached,
45+
TLS-protocol-error,
46+
TLS-certificate-error,
47+
TLS-alert-received(TLS-alert-received-payload),
48+
HTTP-request-denied,
49+
HTTP-request-length-required,
50+
HTTP-request-body-size(option<u64>),
51+
HTTP-request-method-invalid,
52+
HTTP-request-URI-invalid,
53+
HTTP-request-URI-too-long,
54+
HTTP-request-header-section-size(option<u32>),
55+
HTTP-request-header-size(option<field-size-payload>),
56+
HTTP-request-trailer-section-size(option<u32>),
57+
HTTP-request-trailer-size(field-size-payload),
58+
HTTP-response-incomplete,
59+
HTTP-response-header-section-size(option<u32>),
60+
HTTP-response-header-size(field-size-payload),
61+
HTTP-response-body-size(option<u64>),
62+
HTTP-response-trailer-section-size(option<u32>),
63+
HTTP-response-trailer-size(field-size-payload),
64+
HTTP-response-transfer-coding(option<string>),
65+
HTTP-response-content-coding(option<string>),
66+
HTTP-response-timeout,
67+
HTTP-upgrade-failed,
68+
HTTP-protocol-error,
69+
loop-detected,
70+
configuration-error,
71+
/// This is a catch-all error for anything that doesn't fit cleanly into a
72+
/// more specific case. It also includes an optional string for an
73+
/// unstructured description of the error. Users should not depend on the
74+
/// string for diagnosing errors, as it's not required to be consistent
75+
/// between implementations.
76+
internal-error(option<string>)
77+
}
78+
79+
/// Defines the case payload type for `DNS-error` above:
80+
record DNS-error-payload {
81+
rcode: option<string>,
82+
info-code: option<u16>
83+
}
84+
85+
/// Defines the case payload type for `TLS-alert-received` above:
86+
record TLS-alert-received-payload {
87+
alert-id: option<u8>,
88+
alert-message: option<string>
3889
}
3990

91+
/// Defines the case payload type for `HTTP-response-{header,trailer}-size` above:
92+
record field-size-payload {
93+
field-name: option<string>,
94+
field-size: option<u32>
95+
}
96+
97+
/// Attempts to extract a http-related `error` from the stream `error`
98+
/// provided.
99+
///
100+
/// Stream operations which return `stream-error::last-operation-failed` have
101+
/// a payload with more information about the operation that failed. This
102+
/// payload can be passed through to this function to see if there's
103+
/// http-related information about the error to return.
104+
///
105+
/// Note that this function is fallible because not all stream-related errors
106+
/// are http-related errors.
107+
http-error-code: func(err: borrow<stream-error>) -> option<error-code>;
108+
40109
/// This type enumerates the different kinds of errors that may occur when
41110
/// setting or appending to a `fields` resource.
42111
variant header-error {
@@ -261,7 +330,7 @@ interface types {
261330
/// implementation determine how to respond with an HTTP error response.
262331
set: static func(
263332
param: response-outparam,
264-
response: result<outgoing-response, error>,
333+
response: result<outgoing-response, error-code>,
265334
);
266335
}
267336

@@ -336,7 +405,7 @@ interface types {
336405
/// as well as any trailers, were received successfully, or that an error
337406
/// occured receiving them. The optional `trailers` indicates whether or not
338407
/// trailers were present in the body.
339-
get: func() -> option<result<option<trailers>, error>>;
408+
get: func() -> option<result<option<trailers>, error-code>>;
340409
}
341410

342411
/// Represents an outgoing HTTP Response.
@@ -432,7 +501,7 @@ interface types {
432501
/// occured. Errors may also occur while consuming the response body,
433502
/// but those will be reported by the `incoming-body` and its
434503
/// `output-stream` child.
435-
get: func() -> option<result<result<incoming-response, error>>>;
504+
get: func() -> option<result<result<incoming-response, error-code>>>;
436505

437506
}
438507
}

0 commit comments

Comments
 (0)