* Publish a single event to Hydro * @param {string} schema * @param {any} value
(schema, value)
| 84 | * @param {any} value |
| 85 | */ |
| 86 | async publish(schema, value) { |
| 87 | const body = JSON.stringify({ |
| 88 | events: [ |
| 89 | { |
| 90 | schema, |
| 91 | value: JSON.stringify(value), // We must double-encode the value property |
| 92 | cluster: 'potomac', // We only have ability to publish externally to potomac cluster |
| 93 | }, |
| 94 | ], |
| 95 | }) |
| 96 | const token = this.generatePayloadHmac(body) |
| 97 | |
| 98 | const agent = getHttpsAgent() |
| 99 | |
| 100 | const doPost = async () => { |
| 101 | // We *could* exit early on this whole `publish()` method if we know |
| 102 | // we're going to "mock" Hydro anyway, but injecting here, before |
| 103 | // the actual network operation, we make most of this method's code |
| 104 | // execute without actually depending on real network. This is |
| 105 | // good for any functional tests that depend on this, e.g. jest tests. |
| 106 | if (MOCK_HYDRO_POST && !this.forceDisableMock) { |
| 107 | return { statusCode: 200 } |
| 108 | } |
| 109 | return got(this.endpoint, { |
| 110 | method: 'POST', |
| 111 | body, |
| 112 | headers: { |
| 113 | Authorization: `Hydro ${token}`, |
| 114 | 'Content-Type': 'application/json', |
| 115 | 'X-Hydro-App': 'docs-production', |
| 116 | }, |
| 117 | // Because we prefer to handle the status code manually below |
| 118 | throwHttpErrors: false, |
| 119 | agent: { |
| 120 | // Deliberately not setting up a `http` or `http2` agent |
| 121 | // because it won't be used for this particular `got` request. |
| 122 | https: agent, |
| 123 | }, |
| 124 | // See above, where these are configured for the explanation |
| 125 | retry: retryConfiguration, |
| 126 | timeout: timeoutConfiguration, |
| 127 | }) |
| 128 | } |
| 129 | |
| 130 | const res = await statsd.asyncTimer(doPost, 'hydro.response_time')() |
| 131 | |
| 132 | const statTags = [`response_code:${res.statusCode}`] |
| 133 | statsd.increment(`hydro.response_code.${res.statusCode}`, 1, statTags) |
| 134 | statsd.increment('hydro.response_code.all', 1, statTags) |
| 135 | |
| 136 | // Track hydro exceptions in Sentry, |
| 137 | // but don't track 5xx because we can't do anything about service availability |
| 138 | if (res.statusCode !== 200 && res.statusCode < 500) { |
| 139 | const hydroText = await res.text() |
| 140 | const err = new Error( |
| 141 | `Hydro request failed: (${res.statusCode}) ${res.statusMessage} - ${hydroText}` |
| 142 | ) |
| 143 | err.status = res.statusCode |
no test coverage detected