Skip to content

Commit

Permalink
Resolve "Custom error raising method"
Browse files Browse the repository at this point in the history
  • Loading branch information
edgarrmondragon committed Nov 18, 2021
1 parent 7fd90b7 commit bd12947
Show file tree
Hide file tree
Showing 13 changed files with 311 additions and 49 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### New

- Tap SDK: New method `RESTStream.validate_response` to allow developers to use custom validation of HTTP responses ([#207](https://gitlab.com/meltano/sdk/-/issues/207), [!195](https://gitlab.com/meltano/sdk/-/merge_requests/195))
- Tap SDK: New method `RESTStream.request_decorator` to allow developers to use custom back-off parameters ([#137](https://gitlab.com/meltano/sdk/-/issues/137), [!195](https://gitlab.com/meltano/sdk/-/merge_requests/195))

### Changes

### Fixes
Expand Down
6 changes: 6 additions & 0 deletions docs/classes/singer_sdk.exceptions.FatalAPIError.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
singer\_sdk.exceptions.FatalAPIError
==============================================

.. currentmodule:: singer_sdk.exceptions

.. autoexception:: FatalAPIError
6 changes: 6 additions & 0 deletions docs/classes/singer_sdk.exceptions.RetriableAPIError.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
singer\_sdk.exceptions.RetriableAPIError
==============================================

.. currentmodule:: singer_sdk.exceptions

.. autoexception:: RetriableAPIError
51 changes: 51 additions & 0 deletions docs/code_samples.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,16 @@ To add your project to this list, please

These are code samples taken from other projects. Use these as a reference if you get stuck.

- [A simple Tap class definition with two streams](./code_samples.html#a-simple-tap-class-definition-with-two-streams)
- [Define a simple GraphQL-based stream with schema defined in a file](./code_samples.html#define-a-simple-graphql-based-stream-with-schema-defined-in-a-file)
- [Define a REST-based stream with a JSONPath expression](./code_samples.html#define-a-rest-based-stream-with-a-jsonpath-expression)
- [Dynamically discovering `schema` for a stream](./code_samples.html#dynamically-discovering-schema-for-a-stream)
- [Initialize a collection of tap streams with differing types](./code_samples.html#initialize-a-collection-of-tap-streams-with-differing-types)
- [Run the standard built-in tap tests](./code_samples.html#run-the-standard-built-in-tap-tests)
- [Make all streams reuse the same authenticator instance](./code_samples.html#make-all-streams-reuse-the-same-authenticator-instance)
- [Make a stream reuse the same authenticator instance for all requests](./code_samples.html#make-a-stream-reuse-the-same-authenticator-instance-for-all-requests)
- [Custom response validation](./code_samples.html#custom-response-validation)

### A simple Tap class definition with two streams

```python
Expand Down Expand Up @@ -233,6 +243,47 @@ class CachedAuthStream(RESTStream):
return APIAuthenticatorBase(stream=self)
```

### Custom response validation

Some APIs deviate from HTTP status codes to report failures. For those cases,
you can override [`RESTStream.validate_response()`](./classes/singer_sdk.RESTStream.html#singer_sdk.RESTStream.validate_response)
and raise [`FatalAPIError`](./classes/singer_sdk.exceptions.FatalAPIError)
if an unrecoverable error is detected. If the API also has transient errors, either client-side
like rate limits, or server-side like temporary 5xx, you can raise
[`RetriableAPIError`](./classes/singer_sdk.exceptions.RetriableAPIError)
and the request will be retried with back-off:

```python
from enum import Enum
from singer_sdk.exceptions import FatalAPIError, RetriableAPIError
from singer_sdk.streams.rest import RESTStream

class CustomResponseValidationStream(RESTStream):
"""Stream with non-conventional error response."""

url_base = "https://badapi.test"
name = "non_conventional"
schema = {"type": "object", "properties": {}}
path = "/dummy

class StatusMessage(str, Enum):
"""Possible status messages."""

OK = "OK"
ERROR = "ERROR"
UNAVAILABLE = "UNAVAILABLE"

def validate_response(self, response):
# Still catch error status codes
super().validate_response(response)

data = response.json()
if data["status"] == self.StatusMessage.ERROR:
raise FatalAPIError("Error message found :(")
if data["status"] == self.StatusMessage.UNAVAILABLE:
raise RetriableAPIError("API is unavailable")
```

## Additional Resources

More links, resources, and example solutions are available from community
Expand Down
Binary file added docs/images/200.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions docs/reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,12 @@ Exception Types
:template: class.rst

exceptions.ConfigValidationError
exceptions.FatalAPIError
exceptions.InvalidStreamSortException
exceptions.MapExpressionError
exceptions.MaxRecordsLimitException
exceptions.RecordsWitoutSchemaException
exceptions.RetriableAPIError
exceptions.StreamMapConfigError
exceptions.TapStreamConnectionFailure
exceptions.TooManyRecordsException
Loading

0 comments on commit bd12947

Please sign in to comment.