From b9ce350595e09a9efae92afe7f00daf6aab7b960 Mon Sep 17 00:00:00 2001 From: Yoshida Hiroshi Date: Wed, 17 Jan 2024 11:20:41 +0900 Subject: [PATCH 01/26] =?UTF-8?q?=E3=82=B5=E3=83=BC=E3=83=93=E3=82=B9?= =?UTF-8?q?=E6=AF=8E=E3=81=AB=20status=20code=20=E3=81=A8=E3=82=A8?= =?UTF-8?q?=E3=83=A9=E3=83=BC=E3=83=A1=E3=83=83=E3=82=BB=E3=83=BC=E3=82=B8?= =?UTF-8?q?=E3=82=92=E6=8C=87=E5=AE=9A=E3=81=A7=E3=81=8D=E3=82=8B=E3=82=88?= =?UTF-8?q?=E3=81=86=E3=81=AB=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- amazon_transcribe.go | 11 +++++++++++ errors.go | 20 ++++++++++++++++++++ handler.go | 9 +++++++-- 3 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 errors.go diff --git a/amazon_transcribe.go b/amazon_transcribe.go index 9501238..844a2d5 100644 --- a/amazon_transcribe.go +++ b/amazon_transcribe.go @@ -6,6 +6,7 @@ import ( "net/http" "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/transcribestreamingservice" ) @@ -95,6 +96,16 @@ func (at *AmazonTranscribe) Start(ctx context.Context, r io.Reader) (*transcribe resp, err := client.StartStreamTranscriptionWithContext(ctx, &input) if err != nil { + if awsErr, ok := err.(awserr.Error); ok { + code, ok := awsTranscribeErrors[awsErr.Code()] + if !ok { + return nil, err + } + return nil, &SuzuError{ + Code: code, + Message: awsErr.Message(), + } + } return nil, err } diff --git a/errors.go b/errors.go new file mode 100644 index 0000000..6bc27d5 --- /dev/null +++ b/errors.go @@ -0,0 +1,20 @@ +package suzu + +import "github.com/aws/aws-sdk-go/service/transcribestreamingservice" + +type SuzuError struct { + Code int + Message string +} + +func (e *SuzuError) Error() string { + return e.Message +} + +var awsTranscribeErrors = map[string]int{ + transcribestreamingservice.ErrCodeLimitExceededException: 429, + transcribestreamingservice.ErrCodeConflictException: 409, + transcribestreamingservice.ErrCodeBadRequestException: 400, + transcribestreamingservice.ErrCodeInternalFailureException: 500, + transcribestreamingservice.ErrCodeServiceUnavailableException: 503, +} diff --git a/handler.go b/handler.go index 1251641..6ee048c 100644 --- a/handler.go +++ b/handler.go @@ -135,8 +135,13 @@ func (s *Server) createSpeechHandler(serviceType string, onResultFunc func(conte Str("channel_id", h.SoraChannelID). Str("connection_id", h.SoraConnectionID). Send() - // TODO: エラー内容で status code を変更する - return echo.NewHTTPError(http.StatusInternalServerError) + if err, ok := err.(*SuzuError); ok { + // SuzuError の場合はその Status Code を返す + return echo.NewHTTPError(err.Code, err) + } + + // SuzuError 以外の場合は 500 を返す + return echo.NewHTTPError(http.StatusInternalServerError, err) } defer reader.Close() From 2d5e330381433960cc9614c9e13aa8441e535f62 Mon Sep 17 00:00:00 2001 From: Yoshida Hiroshi Date: Wed, 17 Jan 2024 12:58:21 +0900 Subject: [PATCH 02/26] =?UTF-8?q?=E3=82=B5=E3=83=BC=E3=83=93=E3=82=B9?= =?UTF-8?q?=E6=AF=8E=E3=81=AB=E5=88=86=E3=81=91=E3=82=8B=E3=81=9F=E3=82=81?= =?UTF-8?q?=E3=80=81=E3=82=A8=E3=83=A9=E3=83=BC=E3=81=AE=E5=AE=9A=E7=BE=A9?= =?UTF-8?q?=E3=82=92=E7=A7=BB=E5=8B=95=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- amazon_transcribe.go | 13 ++++++++++++- errors.go | 10 ---------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/amazon_transcribe.go b/amazon_transcribe.go index 844a2d5..3a5b010 100644 --- a/amazon_transcribe.go +++ b/amazon_transcribe.go @@ -11,6 +11,17 @@ import ( "github.com/aws/aws-sdk-go/service/transcribestreamingservice" ) +var ( + // https://docs.aws.amazon.com/transcribe/latest/APIReference/API_streaming_StartStreamTranscription.html#API_streaming_StartStreamTranscription_Errors + amazonTranscribeStreamingServiceErrors = map[string]int{ + transcribestreamingservice.ErrCodeLimitExceededException: 429, + transcribestreamingservice.ErrCodeConflictException: 409, + transcribestreamingservice.ErrCodeBadRequestException: 400, + transcribestreamingservice.ErrCodeInternalFailureException: 500, + transcribestreamingservice.ErrCodeServiceUnavailableException: 503, + } +) + type AmazonTranscribe struct { LanguageCode string MediaEncoding string @@ -97,7 +108,7 @@ func (at *AmazonTranscribe) Start(ctx context.Context, r io.Reader) (*transcribe resp, err := client.StartStreamTranscriptionWithContext(ctx, &input) if err != nil { if awsErr, ok := err.(awserr.Error); ok { - code, ok := awsTranscribeErrors[awsErr.Code()] + code, ok := amazonTranscribeStreamingServiceErrors[awsErr.Code()] if !ok { return nil, err } diff --git a/errors.go b/errors.go index 6bc27d5..34a3551 100644 --- a/errors.go +++ b/errors.go @@ -1,7 +1,5 @@ package suzu -import "github.com/aws/aws-sdk-go/service/transcribestreamingservice" - type SuzuError struct { Code int Message string @@ -10,11 +8,3 @@ type SuzuError struct { func (e *SuzuError) Error() string { return e.Message } - -var awsTranscribeErrors = map[string]int{ - transcribestreamingservice.ErrCodeLimitExceededException: 429, - transcribestreamingservice.ErrCodeConflictException: 409, - transcribestreamingservice.ErrCodeBadRequestException: 400, - transcribestreamingservice.ErrCodeInternalFailureException: 500, - transcribestreamingservice.ErrCodeServiceUnavailableException: 503, -} From 78c2f95ae16ec035f9cf612a0d112dd5216f572e Mon Sep 17 00:00:00 2001 From: Yoshida Hiroshi Date: Wed, 17 Jan 2024 17:01:13 +0900 Subject: [PATCH 03/26] =?UTF-8?q?=E3=82=A8=E3=83=A9=E3=83=BC=E6=99=82?= =?UTF-8?q?=E3=81=AB=20JSON=20=E3=82=92=E8=BF=94=E3=81=99=E3=82=88?= =?UTF-8?q?=E3=81=86=E3=81=AB=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- amazon_transcribe_handler.go | 23 ++++++++++++++++++----- handler.go | 9 ++++++++- speech_to_text_handler.go | 14 +++++++++----- test_handler.go | 34 +++++++++++++++++++++++++++------- 4 files changed, 62 insertions(+), 18 deletions(-) diff --git a/amazon_transcribe_handler.go b/amazon_transcribe_handler.go index 2a0201e..3052d75 100644 --- a/amazon_transcribe_handler.go +++ b/amazon_transcribe_handler.go @@ -43,11 +43,10 @@ type AwsResult struct { TranscriptionResult } -func NewAwsResult(err error) AwsResult { +func NewAwsResult() AwsResult { return AwsResult{ TranscriptionResult: TranscriptionResult{ - Type: "aws", - Error: err, + Type: "aws", }, } } @@ -62,6 +61,11 @@ func (ar *AwsResult) WithIsPartial(isPartial bool) *AwsResult { return ar } +func (ar *AwsResult) SetMessage(message string) *AwsResult { + ar.Message = message + return ar +} + func (h *AmazonTranscribeHandler) Handle(ctx context.Context, reader io.Reader) (*io.PipeReader, error) { at := NewAmazonTranscribe(h.Config, h.LanguageCode, int64(h.SampleRate), int64(h.ChannelCount)) @@ -111,7 +115,7 @@ func (h *AmazonTranscribeHandler) Handle(ctx context.Context, reader io.Reader) } } - result := NewAwsResult(nil) + result := NewAwsResult() if at.Config.AwsResultIsPartial { result.WithIsPartial(*res.IsPartial) } @@ -123,7 +127,7 @@ func (h *AmazonTranscribeHandler) Handle(ctx context.Context, reader io.Reader) if alt.Transcript != nil { message = *alt.Transcript } - result.Message = message + result.SetMessage(message) if err := encoder.Encode(result); err != nil { w.CloseWithError(err) return @@ -138,6 +142,15 @@ func (h *AmazonTranscribeHandler) Handle(ctx context.Context, reader io.Reader) } if err := stream.Err(); err != nil { + errResponse := NewSuzuErrorResponse(err.Error()) + if err := encoder.Encode(errResponse); err != nil { + zlog.Error(). + Err(err). + Str("channel_id", h.ChannelID). + Str("connection_id", h.ConnectionID). + Send() + } + // 復帰が不可能なエラー以外は再接続を試みる switch err.(type) { case *transcribestreamingservice.LimitExceededException, diff --git a/handler.go b/handler.go index 6ee048c..cd53e92 100644 --- a/handler.go +++ b/handler.go @@ -26,10 +26,17 @@ var ( type TranscriptionResult struct { Message string `json:"message,omitempty"` - Error error `json:"error,omitempty"` + Reason string `json:"reason,omitempty"` Type string `json:"type"` } +func NewSuzuErrorResponse(message string) TranscriptionResult { + return TranscriptionResult{ + Type: "error", + Reason: message, + } +} + func getServiceHandler(serviceType string, config Config, channelID, connectionID string, sampleRate uint32, channelCount uint16, languageCode string, onResultFunc any) (serviceHandlerInterface, error) { newHandlerFunc, err := NewServiceHandlerFuncs.get(serviceType) if err != nil { diff --git a/speech_to_text_handler.go b/speech_to_text_handler.go index 0f28878..4e3fbcd 100644 --- a/speech_to_text_handler.go +++ b/speech_to_text_handler.go @@ -45,11 +45,10 @@ type GcpResult struct { TranscriptionResult } -func NewGcpResult(err error) GcpResult { +func NewGcpResult() GcpResult { return GcpResult{ TranscriptionResult: TranscriptionResult{ - Type: "gcp", - Error: err, + Type: "gcp", }, } } @@ -64,6 +63,11 @@ func (gr *GcpResult) WithStability(stability float32) *GcpResult { return gr } +func (gr *GcpResult) SetMessage(message string) *GcpResult { + gr.Message = message + return gr +} + func (h *SpeechToTextHandler) Handle(ctx context.Context, reader io.Reader) (*io.PipeReader, error) { stt := NewSpeechToText(h.Config, h.LanguageCode, int32(h.SampleRate), int32(h.ChannelCount)) @@ -151,7 +155,7 @@ func (h *SpeechToTextHandler) Handle(ctx context.Context, reader io.Reader) (*io } } - result := NewGcpResult(nil) + result := NewGcpResult() if stt.Config.GcpResultIsFinal { result.WithIsFinal(res.IsFinal) } @@ -173,7 +177,7 @@ func (h *SpeechToTextHandler) Handle(ctx context.Context, reader io.Reader) (*io } } transcript := alternative.Transcript - result.Message = transcript + result.SetMessage(transcript) if err := encoder.Encode(result); err != nil { w.CloseWithError(err) return diff --git a/test_handler.go b/test_handler.go index 0113fcc..fc9ee2f 100644 --- a/test_handler.go +++ b/test_handler.go @@ -3,6 +3,7 @@ package suzu import ( "context" "encoding/json" + "errors" "fmt" "io" ) @@ -40,12 +41,13 @@ type TestResult struct { TranscriptionResult } -func TestErrorResult(err error) TestResult { +func NewTestResult(channelID, message string) TestResult { return TestResult{ TranscriptionResult: TranscriptionResult{ - Type: "test", - Error: err, + Type: "test", + Message: message, }, + ChannelID: &channelID, } } @@ -53,24 +55,42 @@ func (h *TestHandler) Handle(ctx context.Context, reader io.Reader) (*io.PipeRea r, w := io.Pipe() go func() { + c := 0 encoder := json.NewEncoder(w) for { + c += 1 buf := make([]byte, FrameSize) n, err := reader.Read(buf) if err != nil { + errResponse := NewSuzuErrorResponse(err.Error()) + if err := encoder.Encode(errResponse); err != nil { + // TODO: ログを書く + } w.CloseWithError(err) return } + if c > 10 { + err := errors.New("c > 10") + errResponse := NewSuzuErrorResponse(err.Error()) + if err := encoder.Encode(errResponse); err != nil { + w.CloseWithError(err) + return + } + } + if n > 0 { - var result TestResult - result.Type = "test" - result.Message = fmt.Sprintf("n: %d", n) - result.ChannelID = &[]string{"ch_0"}[0] + message := fmt.Sprintf("n: %d", n) + channelID := &[]string{"ch_0"}[0] + result := NewTestResult(*channelID, message) if h.OnResultFunc != nil { if err := h.OnResultFunc(ctx, w, h.ChannelID, h.ConnectionID, h.LanguageCode, result); err != nil { + errResponse := NewSuzuErrorResponse(err.Error()) + if err := encoder.Encode(errResponse); err != nil { + // TODO: ログを書く + } w.CloseWithError(err) return } From e1c91c146acb348322f0301ab3314e50a49fdd77 Mon Sep 17 00:00:00 2001 From: Yoshida Hiroshi Date: Thu, 18 Jan 2024 16:34:34 +0900 Subject: [PATCH 04/26] =?UTF-8?q?=E5=8B=95=E4=BD=9C=E7=A2=BA=E8=AA=8D?= =?UTF-8?q?=E7=94=A8=E3=81=AE=E3=82=B3=E3=83=BC=E3=83=89=E3=82=92=E5=89=8A?= =?UTF-8?q?=E9=99=A4=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test_handler.go | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/test_handler.go b/test_handler.go index fc9ee2f..f7bfc5d 100644 --- a/test_handler.go +++ b/test_handler.go @@ -3,7 +3,6 @@ package suzu import ( "context" "encoding/json" - "errors" "fmt" "io" ) @@ -55,11 +54,9 @@ func (h *TestHandler) Handle(ctx context.Context, reader io.Reader) (*io.PipeRea r, w := io.Pipe() go func() { - c := 0 encoder := json.NewEncoder(w) for { - c += 1 buf := make([]byte, FrameSize) n, err := reader.Read(buf) if err != nil { @@ -71,15 +68,6 @@ func (h *TestHandler) Handle(ctx context.Context, reader io.Reader) (*io.PipeRea return } - if c > 10 { - err := errors.New("c > 10") - errResponse := NewSuzuErrorResponse(err.Error()) - if err := encoder.Encode(errResponse); err != nil { - w.CloseWithError(err) - return - } - } - if n > 0 { message := fmt.Sprintf("n: %d", n) channelID := &[]string{"ch_0"}[0] From 20bca3649e00eef977b30c7ec091247251b2b24b Mon Sep 17 00:00:00 2001 From: Yoshida Hiroshi Date: Fri, 19 Jan 2024 10:47:21 +0900 Subject: [PATCH 05/26] =?UTF-8?q?=E3=82=B3=E3=82=B9=E3=83=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test_handler_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_handler_test.go b/test_handler_test.go index 43fe17a..5368aec 100644 --- a/test_handler_test.go +++ b/test_handler_test.go @@ -125,7 +125,7 @@ func TestSpeechHandler(t *testing.T) { lastMessage = result.Message } // TODO: テストデータは固定のため、すべてのメッセージを確認する - assert.Equal(t, lastMessage, "n: 3") + assert.Equal(t, "n: 3", lastMessage) } }) From 702bef0cfcec638627b80567aa8310632033be3f Mon Sep 17 00:00:00 2001 From: Yoshida Hiroshi Date: Fri, 19 Jan 2024 10:47:54 +0900 Subject: [PATCH 06/26] =?UTF-8?q?EOF=20=E3=81=AE=E5=A0=B4=E5=90=88?= =?UTF-8?q?=E3=81=AF=20JSON=20=E3=82=92=E8=BF=94=E3=81=95=E3=81=AA?= =?UTF-8?q?=E3=81=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test_handler.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/test_handler.go b/test_handler.go index f7bfc5d..4b143fe 100644 --- a/test_handler.go +++ b/test_handler.go @@ -60,9 +60,11 @@ func (h *TestHandler) Handle(ctx context.Context, reader io.Reader) (*io.PipeRea buf := make([]byte, FrameSize) n, err := reader.Read(buf) if err != nil { - errResponse := NewSuzuErrorResponse(err.Error()) - if err := encoder.Encode(errResponse); err != nil { - // TODO: ログを書く + if err != io.EOF { + errResponse := NewSuzuErrorResponse(err.Error()) + if err := encoder.Encode(errResponse); err != nil { + // TODO: ログを書く + } } w.CloseWithError(err) return From 8c53f616ae8e2d141b9f80566b6cd7b296b29683 Mon Sep 17 00:00:00 2001 From: Yoshida Hiroshi Date: Fri, 19 Jan 2024 14:08:31 +0900 Subject: [PATCH 07/26] =?UTF-8?q?=E3=82=B9=E3=83=88=E3=83=AA=E3=83=BC?= =?UTF-8?q?=E3=83=A0=E3=81=A7=E3=81=AE=E3=82=A8=E3=83=A9=E3=83=BC=E3=81=AE?= =?UTF-8?q?=E3=83=86=E3=82=B9=E3=83=88=E3=82=92=E8=BF=BD=E5=8A=A0=E3=81=99?= =?UTF-8?q?=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test_handler_test.go | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/test_handler_test.go b/test_handler_test.go index 5368aec..05a33a0 100644 --- a/test_handler_test.go +++ b/test_handler_test.go @@ -359,4 +359,47 @@ func TestSpeechHandler(t *testing.T) { }) + t.Run("stream error", func(t *testing.T) { + r := readDumpFile(t, "testdata/dump.jsonl", 0) + defer r.Close() + + e := echo.New() + req := httptest.NewRequest("POST", path, r) + req.Header.Set("sora-audio-streaming-language-code", "ja-JP") + req.Proto = "HTTP/2.0" + req.ProtoMajor = 2 + req.ProtoMinor = 0 + rec := httptest.NewRecorder() + c := e.NewContext(req, rec) + + h := s.createSpeechHandler(serviceType, func(ctx context.Context, w io.WriteCloser, chnanelID, connectionID, languageCode string, results any) error { + return fmt.Errorf("STREAM-ERROR") + }) + err := h(c) + if assert.Error(t, err) { + assert.Equal(t, http.StatusOK, rec.Code) + + delim := []byte("\n")[0] + for { + line, err := rec.Body.ReadBytes(delim) + if err != nil { + if !assert.ErrorIs(t, err, io.EOF) { + t.Logf("STREAM-ERROR: %v\n", err) + } + break + } + var result TranscriptionResult + if err := json.Unmarshal(line, &result); err != nil { + t.Error(err) + } + + assert.Equal(t, "error", result.Type) + if assert.NotEmpty(t, result.Reason) { + assert.Equal(t, "STREAM-ERROR", result.Reason) + assert.Empty(t, result.Message) + } + } + } + + }) } From c3bf4d2568b85f190dfece8a65f091e4c9a8eb9f Mon Sep 17 00:00:00 2001 From: Yoshida Hiroshi Date: Fri, 19 Jan 2024 14:09:18 +0900 Subject: [PATCH 08/26] =?UTF-8?q?OnResultFunc=20=E3=81=A7=E3=82=A8?= =?UTF-8?q?=E3=83=A9=E3=83=BC=E3=81=AB=E3=81=AA=E3=81=A3=E3=81=9F=E5=A0=B4?= =?UTF-8?q?=E5=90=88=E3=82=82=20JSON=20=E3=82=92=E8=BF=94=E3=81=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- amazon_transcribe_handler.go | 4 ++++ speech_to_text_handler.go | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/amazon_transcribe_handler.go b/amazon_transcribe_handler.go index 3052d75..705b15b 100644 --- a/amazon_transcribe_handler.go +++ b/amazon_transcribe_handler.go @@ -103,6 +103,10 @@ func (h *AmazonTranscribeHandler) Handle(ctx context.Context, reader io.Reader) case *transcribestreamingservice.TranscriptEvent: if h.OnResultFunc != nil { if err := h.OnResultFunc(ctx, w, h.ChannelID, h.ConnectionID, h.LanguageCode, e.Transcript.Results); err != nil { + errResponse := NewSuzuErrorResponse(err.Error()) + if err := encoder.Encode(errResponse); err != nil { + // TODO: ログを書く + } w.CloseWithError(err) return } diff --git a/speech_to_text_handler.go b/speech_to_text_handler.go index 4e3fbcd..7fbe192 100644 --- a/speech_to_text_handler.go +++ b/speech_to_text_handler.go @@ -144,6 +144,10 @@ func (h *SpeechToTextHandler) Handle(ctx context.Context, reader io.Reader) (*io if h.OnResultFunc != nil { if err := h.OnResultFunc(ctx, w, h.ChannelID, h.ConnectionID, h.LanguageCode, resp.Results); err != nil { + errResponse := NewSuzuErrorResponse(err.Error()) + if err := encoder.Encode(errResponse); err != nil { + // TODO: ログを書く + } w.CloseWithError(err) return } From 41562cbdd3acfdab401e0c96452a5e0f4e45cdea Mon Sep 17 00:00:00 2001 From: Yoshida Hiroshi Date: Wed, 24 Jan 2024 12:53:40 +0900 Subject: [PATCH 09/26] =?UTF-8?q?=E3=82=A8=E3=83=A9=E3=83=BC=E3=83=A1?= =?UTF-8?q?=E3=83=83=E3=82=BB=E3=83=BC=E3=82=B8=E9=80=81=E4=BF=A1=E6=99=82?= =?UTF-8?q?=E3=81=AE=E3=82=A8=E3=83=A9=E3=83=BC=E3=82=92=E3=83=AD=E3=82=B0?= =?UTF-8?q?=E3=81=AB=E5=87=BA=E5=8A=9B=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- amazon_transcribe_handler.go | 9 ++++++--- speech_to_text_handler.go | 9 ++++++--- test_handler.go | 20 ++++++++++++++------ 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/amazon_transcribe_handler.go b/amazon_transcribe_handler.go index 705b15b..fe6866c 100644 --- a/amazon_transcribe_handler.go +++ b/amazon_transcribe_handler.go @@ -103,9 +103,12 @@ func (h *AmazonTranscribeHandler) Handle(ctx context.Context, reader io.Reader) case *transcribestreamingservice.TranscriptEvent: if h.OnResultFunc != nil { if err := h.OnResultFunc(ctx, w, h.ChannelID, h.ConnectionID, h.LanguageCode, e.Transcript.Results); err != nil { - errResponse := NewSuzuErrorResponse(err.Error()) - if err := encoder.Encode(errResponse); err != nil { - // TODO: ログを書く + if err := encoder.Encode(NewSuzuErrorResponse(err.Error())); err != nil { + zlog.Error(). + Err(err). + Str("channel_id", h.ChannelID). + Str("connection_id", h.ConnectionID). + Send() } w.CloseWithError(err) return diff --git a/speech_to_text_handler.go b/speech_to_text_handler.go index 7fbe192..5681390 100644 --- a/speech_to_text_handler.go +++ b/speech_to_text_handler.go @@ -144,9 +144,12 @@ func (h *SpeechToTextHandler) Handle(ctx context.Context, reader io.Reader) (*io if h.OnResultFunc != nil { if err := h.OnResultFunc(ctx, w, h.ChannelID, h.ConnectionID, h.LanguageCode, resp.Results); err != nil { - errResponse := NewSuzuErrorResponse(err.Error()) - if err := encoder.Encode(errResponse); err != nil { - // TODO: ログを書く + if err := encoder.Encode(NewSuzuErrorResponse(err.Error())); err != nil { + zlog.Error(). + Err(err). + Str("channel_id", h.ChannelID). + Str("connection_id", h.ConnectionID). + Send() } w.CloseWithError(err) return diff --git a/test_handler.go b/test_handler.go index 4b143fe..15fc137 100644 --- a/test_handler.go +++ b/test_handler.go @@ -5,6 +5,8 @@ import ( "encoding/json" "fmt" "io" + + zlog "github.com/rs/zerolog/log" ) func init() { @@ -61,9 +63,12 @@ func (h *TestHandler) Handle(ctx context.Context, reader io.Reader) (*io.PipeRea n, err := reader.Read(buf) if err != nil { if err != io.EOF { - errResponse := NewSuzuErrorResponse(err.Error()) - if err := encoder.Encode(errResponse); err != nil { - // TODO: ログを書く + if err := encoder.Encode(NewSuzuErrorResponse(err.Error())); err != nil { + zlog.Error(). + Err(err). + Str("channel_id", h.ChannelID). + Str("connection_id", h.ConnectionID). + Send() } } w.CloseWithError(err) @@ -77,9 +82,12 @@ func (h *TestHandler) Handle(ctx context.Context, reader io.Reader) (*io.PipeRea if h.OnResultFunc != nil { if err := h.OnResultFunc(ctx, w, h.ChannelID, h.ConnectionID, h.LanguageCode, result); err != nil { - errResponse := NewSuzuErrorResponse(err.Error()) - if err := encoder.Encode(errResponse); err != nil { - // TODO: ログを書く + if err := encoder.Encode(NewSuzuErrorResponse(err.Error())); err != nil { + zlog.Error(). + Err(err). + Str("channel_id", h.ChannelID). + Str("connection_id", h.ConnectionID). + Send() } w.CloseWithError(err) return From 04abd753efc5a4310fdf3b2af7108a6793d53597 Mon Sep 17 00:00:00 2001 From: Yoshida Hiroshi Date: Thu, 25 Jan 2024 16:43:25 +0900 Subject: [PATCH 10/26] =?UTF-8?q?=E7=B5=82=E4=BA=86=E6=99=82=E3=81=AE?= =?UTF-8?q?=E3=83=A1=E3=83=83=E3=82=BB=E3=83=BC=E3=82=B8=E3=82=92=E3=82=B9?= =?UTF-8?q?=E3=83=88=E3=83=AA=E3=83=BC=E3=83=A0=E3=81=AB=E9=80=81=E3=82=89?= =?UTF-8?q?=E3=81=AA=E3=81=84=E3=82=88=E3=81=86=E3=81=AB=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- handler.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/handler.go b/handler.go index cd53e92..5e7b8ba 100644 --- a/handler.go +++ b/handler.go @@ -144,7 +144,7 @@ func (s *Server) createSpeechHandler(serviceType string, onResultFunc func(conte Send() if err, ok := err.(*SuzuError); ok { // SuzuError の場合はその Status Code を返す - return echo.NewHTTPError(err.Code, err) + return c.NoContent(err.Code) } // SuzuError 以外の場合は 500 を返す From 85a442fe827c306e0da047e24b15eb0b87b0638d Mon Sep 17 00:00:00 2001 From: Yoshida Hiroshi Date: Thu, 25 Jan 2024 16:50:16 +0900 Subject: [PATCH 11/26] =?UTF-8?q?=E5=85=B1=E9=80=9A=E3=82=A8=E3=83=A9?= =?UTF-8?q?=E3=83=BC=E3=82=92=E8=BF=BD=E5=8A=A0=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- amazon_transcribe.go | 47 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/amazon_transcribe.go b/amazon_transcribe.go index 3a5b010..e537875 100644 --- a/amazon_transcribe.go +++ b/amazon_transcribe.go @@ -11,14 +11,55 @@ import ( "github.com/aws/aws-sdk-go/service/transcribestreamingservice" ) +const ( + AccessDeniedException = "AccessDeniedException" + IncompleteSignature = "IncompleteSignature" + InternalFailure = "InternalFailure" + InvalidAction = "InvalidAction" + InvalidClientTokenID = "InvalidClientTokenId" + InvalidParameterCombination = "InvalidParameterCombination" + InvalidParameterValue = "InvalidParameterValue" + InvalidQueryParameter = "InvalidQueryParameter" + MalformedQueryString = "MalformedQueryString" + MissingAction = "MissingAction" + MissingAuthenticationToken = "MissingAuthenticationToken" + MissingParameter = "MissingParameter" + NotAuthorized = "NotAuthorized" + OptInRequired = "OptInRequired" + RequestExpired = "RequestExpired" + ServiceUnavailable = "ServiceUnavailable" + ThrottlingException = "ThrottlingException" + ValidationError = "ValidationError" +) + var ( - // https://docs.aws.amazon.com/transcribe/latest/APIReference/API_streaming_StartStreamTranscription.html#API_streaming_StartStreamTranscription_Errors - amazonTranscribeStreamingServiceErrors = map[string]int{ + amazonErrors = map[string]int{ + // https://docs.aws.amazon.com/transcribe/latest/APIReference/API_streaming_StartStreamTranscription.html#API_streaming_StartStreamTranscription_Errors transcribestreamingservice.ErrCodeLimitExceededException: 429, transcribestreamingservice.ErrCodeConflictException: 409, transcribestreamingservice.ErrCodeBadRequestException: 400, transcribestreamingservice.ErrCodeInternalFailureException: 500, transcribestreamingservice.ErrCodeServiceUnavailableException: 503, + + // https://docs.aws.amazon.com/transcribe/latest/APIReference/CommonErrors.html + AccessDeniedException: 400, + IncompleteSignature: 400, + InternalFailure: 500, + InvalidAction: 400, + InvalidClientTokenID: 403, + InvalidParameterCombination: 400, + InvalidParameterValue: 400, + InvalidQueryParameter: 400, + MalformedQueryString: 404, + MissingAction: 400, + MissingAuthenticationToken: 403, + MissingParameter: 400, + NotAuthorized: 400, + OptInRequired: 403, + RequestExpired: 400, + ServiceUnavailable: 503, + ThrottlingException: 400, + ValidationError: 400, } ) @@ -108,7 +149,7 @@ func (at *AmazonTranscribe) Start(ctx context.Context, r io.Reader) (*transcribe resp, err := client.StartStreamTranscriptionWithContext(ctx, &input) if err != nil { if awsErr, ok := err.(awserr.Error); ok { - code, ok := amazonTranscribeStreamingServiceErrors[awsErr.Code()] + code, ok := amazonErrors[awsErr.Code()] if !ok { return nil, err } From c9b02bbd54de0a9337ab2592d3644bbd1d9250e3 Mon Sep 17 00:00:00 2001 From: Yoshida Hiroshi Date: Tue, 30 Jan 2024 15:14:26 +0900 Subject: [PATCH 12/26] =?UTF-8?q?err=20=E3=81=8C=20awserr.RequestFailure?= =?UTF-8?q?=20=E3=81=AE=E5=A0=B4=E5=90=88=E3=81=AF=20StatusCode=20?= =?UTF-8?q?=E3=82=92=E5=8F=96=E5=BE=97=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- amazon_transcribe.go | 62 +++----------------------------------------- 1 file changed, 4 insertions(+), 58 deletions(-) diff --git a/amazon_transcribe.go b/amazon_transcribe.go index e537875..0b0e4da 100644 --- a/amazon_transcribe.go +++ b/amazon_transcribe.go @@ -11,58 +11,6 @@ import ( "github.com/aws/aws-sdk-go/service/transcribestreamingservice" ) -const ( - AccessDeniedException = "AccessDeniedException" - IncompleteSignature = "IncompleteSignature" - InternalFailure = "InternalFailure" - InvalidAction = "InvalidAction" - InvalidClientTokenID = "InvalidClientTokenId" - InvalidParameterCombination = "InvalidParameterCombination" - InvalidParameterValue = "InvalidParameterValue" - InvalidQueryParameter = "InvalidQueryParameter" - MalformedQueryString = "MalformedQueryString" - MissingAction = "MissingAction" - MissingAuthenticationToken = "MissingAuthenticationToken" - MissingParameter = "MissingParameter" - NotAuthorized = "NotAuthorized" - OptInRequired = "OptInRequired" - RequestExpired = "RequestExpired" - ServiceUnavailable = "ServiceUnavailable" - ThrottlingException = "ThrottlingException" - ValidationError = "ValidationError" -) - -var ( - amazonErrors = map[string]int{ - // https://docs.aws.amazon.com/transcribe/latest/APIReference/API_streaming_StartStreamTranscription.html#API_streaming_StartStreamTranscription_Errors - transcribestreamingservice.ErrCodeLimitExceededException: 429, - transcribestreamingservice.ErrCodeConflictException: 409, - transcribestreamingservice.ErrCodeBadRequestException: 400, - transcribestreamingservice.ErrCodeInternalFailureException: 500, - transcribestreamingservice.ErrCodeServiceUnavailableException: 503, - - // https://docs.aws.amazon.com/transcribe/latest/APIReference/CommonErrors.html - AccessDeniedException: 400, - IncompleteSignature: 400, - InternalFailure: 500, - InvalidAction: 400, - InvalidClientTokenID: 403, - InvalidParameterCombination: 400, - InvalidParameterValue: 400, - InvalidQueryParameter: 400, - MalformedQueryString: 404, - MissingAction: 400, - MissingAuthenticationToken: 403, - MissingParameter: 400, - NotAuthorized: 400, - OptInRequired: 403, - RequestExpired: 400, - ServiceUnavailable: 503, - ThrottlingException: 400, - ValidationError: 400, - } -) - type AmazonTranscribe struct { LanguageCode string MediaEncoding string @@ -148,14 +96,12 @@ func (at *AmazonTranscribe) Start(ctx context.Context, r io.Reader) (*transcribe resp, err := client.StartStreamTranscriptionWithContext(ctx, &input) if err != nil { - if awsErr, ok := err.(awserr.Error); ok { - code, ok := amazonErrors[awsErr.Code()] - if !ok { - return nil, err - } + if reqErr, ok := err.(awserr.RequestFailure); ok { + code := reqErr.StatusCode() + message := reqErr.Message() return nil, &SuzuError{ Code: code, - Message: awsErr.Message(), + Message: message, } } return nil, err From a4be6feca0aa8076803f46b5e19a24343ae6fb15 Mon Sep 17 00:00:00 2001 From: Yoshida Hiroshi Date: Tue, 30 Jan 2024 15:21:20 +0900 Subject: [PATCH 13/26] =?UTF-8?q?=E5=9E=8B=E3=82=92=E5=A4=89=E6=9B=B4?= =?UTF-8?q?=E3=81=97=E3=81=A6=E4=BD=BF=E3=81=84=E3=82=84=E3=81=99=E3=81=8F?= =?UTF-8?q?=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- amazon_transcribe_handler.go | 5 ++--- handler.go | 4 ++-- speech_to_text_handler.go | 2 +- test_handler.go | 4 ++-- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/amazon_transcribe_handler.go b/amazon_transcribe_handler.go index fe6866c..5cff578 100644 --- a/amazon_transcribe_handler.go +++ b/amazon_transcribe_handler.go @@ -103,7 +103,7 @@ func (h *AmazonTranscribeHandler) Handle(ctx context.Context, reader io.Reader) case *transcribestreamingservice.TranscriptEvent: if h.OnResultFunc != nil { if err := h.OnResultFunc(ctx, w, h.ChannelID, h.ConnectionID, h.LanguageCode, e.Transcript.Results); err != nil { - if err := encoder.Encode(NewSuzuErrorResponse(err.Error())); err != nil { + if err := encoder.Encode(NewSuzuErrorResponse(err)); err != nil { zlog.Error(). Err(err). Str("channel_id", h.ChannelID). @@ -149,8 +149,7 @@ func (h *AmazonTranscribeHandler) Handle(ctx context.Context, reader io.Reader) } if err := stream.Err(); err != nil { - errResponse := NewSuzuErrorResponse(err.Error()) - if err := encoder.Encode(errResponse); err != nil { + if err := encoder.Encode(NewSuzuErrorResponse(err)); err != nil { zlog.Error(). Err(err). Str("channel_id", h.ChannelID). diff --git a/handler.go b/handler.go index 5e7b8ba..c348a42 100644 --- a/handler.go +++ b/handler.go @@ -30,10 +30,10 @@ type TranscriptionResult struct { Type string `json:"type"` } -func NewSuzuErrorResponse(message string) TranscriptionResult { +func NewSuzuErrorResponse(err error) TranscriptionResult { return TranscriptionResult{ Type: "error", - Reason: message, + Reason: err.Error(), } } diff --git a/speech_to_text_handler.go b/speech_to_text_handler.go index 5681390..4441b30 100644 --- a/speech_to_text_handler.go +++ b/speech_to_text_handler.go @@ -144,7 +144,7 @@ func (h *SpeechToTextHandler) Handle(ctx context.Context, reader io.Reader) (*io if h.OnResultFunc != nil { if err := h.OnResultFunc(ctx, w, h.ChannelID, h.ConnectionID, h.LanguageCode, resp.Results); err != nil { - if err := encoder.Encode(NewSuzuErrorResponse(err.Error())); err != nil { + if err := encoder.Encode(NewSuzuErrorResponse(err)); err != nil { zlog.Error(). Err(err). Str("channel_id", h.ChannelID). diff --git a/test_handler.go b/test_handler.go index 15fc137..a8c3912 100644 --- a/test_handler.go +++ b/test_handler.go @@ -63,7 +63,7 @@ func (h *TestHandler) Handle(ctx context.Context, reader io.Reader) (*io.PipeRea n, err := reader.Read(buf) if err != nil { if err != io.EOF { - if err := encoder.Encode(NewSuzuErrorResponse(err.Error())); err != nil { + if err := encoder.Encode(NewSuzuErrorResponse(err)); err != nil { zlog.Error(). Err(err). Str("channel_id", h.ChannelID). @@ -82,7 +82,7 @@ func (h *TestHandler) Handle(ctx context.Context, reader io.Reader) (*io.PipeRea if h.OnResultFunc != nil { if err := h.OnResultFunc(ctx, w, h.ChannelID, h.ConnectionID, h.LanguageCode, result); err != nil { - if err := encoder.Encode(NewSuzuErrorResponse(err.Error())); err != nil { + if err := encoder.Encode(NewSuzuErrorResponse(err)); err != nil { zlog.Error(). Err(err). Str("channel_id", h.ChannelID). From 017d8b2ce4825bc365ffb3f8c6db3e5a10a9213a Mon Sep 17 00:00:00 2001 From: Yoshida Hiroshi Date: Wed, 31 Jan 2024 12:00:20 +0900 Subject: [PATCH 14/26] =?UTF-8?q?EOF=20=E6=99=82=E3=81=AF=E3=83=AD?= =?UTF-8?q?=E3=82=B0=E3=82=92=E5=87=BA=E3=81=95=E3=81=AA=E3=81=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- amazon_transcribe_handler.go | 13 ++++++++----- speech_to_text_handler.go | 12 +++++++----- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/amazon_transcribe_handler.go b/amazon_transcribe_handler.go index 5cff578..4527a2e 100644 --- a/amazon_transcribe_handler.go +++ b/amazon_transcribe_handler.go @@ -73,11 +73,14 @@ func (h *AmazonTranscribeHandler) Handle(ctx context.Context, reader io.Reader) go func() { defer oggWriter.Close() if err := opus2ogg(ctx, reader, oggWriter, h.SampleRate, h.ChannelCount, h.Config); err != nil { - zlog.Error(). - Err(err). - Str("channel_id", h.ChannelID). - Str("connection_id", h.ConnectionID). - Send() + if err != io.EOF { + zlog.Error(). + Err(err). + Str("channel_id", h.ChannelID). + Str("connection_id", h.ConnectionID). + Send() + } + oggWriter.CloseWithError(err) return } diff --git a/speech_to_text_handler.go b/speech_to_text_handler.go index 4441b30..705ab79 100644 --- a/speech_to_text_handler.go +++ b/speech_to_text_handler.go @@ -75,11 +75,13 @@ func (h *SpeechToTextHandler) Handle(ctx context.Context, reader io.Reader) (*io go func() { defer oggWriter.Close() if err := opus2ogg(ctx, reader, oggWriter, h.SampleRate, h.ChannelCount, h.Config); err != nil { - zlog.Error(). - Err(err). - Str("channel_id", h.ChannelID). - Str("connection_id", h.ConnectionID). - Send() + if err != io.EOF { + zlog.Error(). + Err(err). + Str("channel_id", h.ChannelID). + Str("connection_id", h.ConnectionID). + Send() + } oggWriter.CloseWithError(err) return } From d9c6998b97b2e1f0d0b90402d04070ee15d2ec8b Mon Sep 17 00:00:00 2001 From: Yoshida Hiroshi Date: Fri, 9 Feb 2024 11:54:47 +0900 Subject: [PATCH 15/26] =?UTF-8?q?=E3=82=A8=E3=83=A9=E3=83=BC=E5=88=A4?= =?UTF-8?q?=E5=AE=9A=E3=82=92=E4=BF=AE=E6=AD=A3=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- speech_to_text_handler.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/speech_to_text_handler.go b/speech_to_text_handler.go index 705ab79..a353c11 100644 --- a/speech_to_text_handler.go +++ b/speech_to_text_handler.go @@ -116,7 +116,7 @@ func (h *SpeechToTextHandler) Handle(ctx context.Context, reader io.Reader) (*io w.CloseWithError(err) return } - if status := resp.Error; err != nil { + if status := resp.Error; status != nil { // 音声の長さの上限値に達した場合 code := codes.Code(status.GetCode()) if code == codes.OutOfRange || From 56309d12c7918a63cb2973084493ee6b23093890 Mon Sep 17 00:00:00 2001 From: Yoshida Hiroshi Date: Fri, 9 Feb 2024 12:55:33 +0900 Subject: [PATCH 16/26] =?UTF-8?q?gcp=20=E3=81=AE=E5=A0=B4=E5=90=88?= =?UTF-8?q?=E3=82=82=E3=82=A8=E3=83=A9=E3=83=BC=E6=99=82=E3=81=AB=E3=81=AF?= =?UTF-8?q?=E3=83=A1=E3=83=83=E3=82=BB=E3=83=BC=E3=82=B8=E3=82=92=E9=80=81?= =?UTF-8?q?=E4=BF=A1=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- speech_to_text_handler.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/speech_to_text_handler.go b/speech_to_text_handler.go index a353c11..80accaf 100644 --- a/speech_to_text_handler.go +++ b/speech_to_text_handler.go @@ -3,6 +3,7 @@ package suzu import ( "context" "encoding/json" + "fmt" "io" "strings" @@ -106,6 +107,14 @@ func (h *SpeechToTextHandler) Handle(ctx context.Context, reader io.Reader) (*io Str("connection_id", h.ConnectionID). Send() + if err := encoder.Encode(NewSuzuErrorResponse(err)); err != nil { + zlog.Error(). + Err(err). + Str("channel_id", h.ChannelID). + Str("connection_id", h.ConnectionID). + Send() + } + if (strings.Contains(err.Error(), "code = OutOfRange")) || (strings.Contains(err.Error(), "code = InvalidArgument")) || (strings.Contains(err.Error(), "code = ResourceExhausted")) { @@ -117,6 +126,14 @@ func (h *SpeechToTextHandler) Handle(ctx context.Context, reader io.Reader) (*io return } if status := resp.Error; status != nil { + err := fmt.Errorf(status.GetMessage()) + if err := encoder.Encode(NewSuzuErrorResponse(err)); err != nil { + zlog.Error(). + Err(err). + Str("channel_id", h.ChannelID). + Str("connection_id", h.ConnectionID). + Send() + } // 音声の長さの上限値に達した場合 code := codes.Code(status.GetCode()) if code == codes.OutOfRange || From 0a76bc1c894f91f3f654c9d0c82403ca7dc4e657 Mon Sep 17 00:00:00 2001 From: Yoshida Hiroshi Date: Fri, 9 Feb 2024 17:00:05 +0900 Subject: [PATCH 17/26] =?UTF-8?q?=E3=83=AA=E3=83=88=E3=83=A9=E3=82=A4?= =?UTF-8?q?=E6=9D=A1=E4=BB=B6=E6=99=82=E3=81=AB=E3=81=AF=E3=82=A8=E3=83=A9?= =?UTF-8?q?=E3=83=BC=E3=83=A1=E3=83=83=E3=82=BB=E3=83=BC=E3=82=B8=E3=81=AF?= =?UTF-8?q?=E9=80=81=E3=82=89=E3=81=AA=E3=81=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- amazon_transcribe_handler.go | 16 ++++++++-------- speech_to_text_handler.go | 34 ++++++++++++++++++---------------- 2 files changed, 26 insertions(+), 24 deletions(-) diff --git a/amazon_transcribe_handler.go b/amazon_transcribe_handler.go index 4527a2e..e23ee0f 100644 --- a/amazon_transcribe_handler.go +++ b/amazon_transcribe_handler.go @@ -152,14 +152,6 @@ func (h *AmazonTranscribeHandler) Handle(ctx context.Context, reader io.Reader) } if err := stream.Err(); err != nil { - if err := encoder.Encode(NewSuzuErrorResponse(err)); err != nil { - zlog.Error(). - Err(err). - Str("channel_id", h.ChannelID). - Str("connection_id", h.ConnectionID). - Send() - } - // 復帰が不可能なエラー以外は再接続を試みる switch err.(type) { case *transcribestreamingservice.LimitExceededException, @@ -172,6 +164,14 @@ func (h *AmazonTranscribeHandler) Handle(ctx context.Context, reader io.Reader) err = ErrServerDisconnected default: + if err := encoder.Encode(NewSuzuErrorResponse(err)); err != nil { + zlog.Error(). + Err(err). + Str("channel_id", h.ChannelID). + Str("connection_id", h.ConnectionID). + Send() + } + } w.CloseWithError(err) diff --git a/speech_to_text_handler.go b/speech_to_text_handler.go index 80accaf..e66bc9f 100644 --- a/speech_to_text_handler.go +++ b/speech_to_text_handler.go @@ -107,14 +107,6 @@ func (h *SpeechToTextHandler) Handle(ctx context.Context, reader io.Reader) (*io Str("connection_id", h.ConnectionID). Send() - if err := encoder.Encode(NewSuzuErrorResponse(err)); err != nil { - zlog.Error(). - Err(err). - Str("channel_id", h.ChannelID). - Str("connection_id", h.ConnectionID). - Send() - } - if (strings.Contains(err.Error(), "code = OutOfRange")) || (strings.Contains(err.Error(), "code = InvalidArgument")) || (strings.Contains(err.Error(), "code = ResourceExhausted")) { @@ -122,11 +114,6 @@ func (h *SpeechToTextHandler) Handle(ctx context.Context, reader io.Reader) (*io return } - w.CloseWithError(err) - return - } - if status := resp.Error; status != nil { - err := fmt.Errorf(status.GetMessage()) if err := encoder.Encode(NewSuzuErrorResponse(err)); err != nil { zlog.Error(). Err(err). @@ -134,6 +121,11 @@ func (h *SpeechToTextHandler) Handle(ctx context.Context, reader io.Reader) (*io Str("connection_id", h.ConnectionID). Send() } + + w.CloseWithError(err) + return + } + if status := resp.Error; status != nil { // 音声の長さの上限値に達した場合 code := codes.Code(status.GetCode()) if code == codes.OutOfRange || @@ -146,16 +138,26 @@ func (h *SpeechToTextHandler) Handle(ctx context.Context, reader io.Reader) (*io Str("connection_id", h.ConnectionID). Int32("code", status.GetCode()). Msg(status.GetMessage()) - err := ErrServerDisconnected - w.CloseWithError(err) + w.CloseWithError(ErrServerDisconnected) return } + + errMessage := status.GetMessage() zlog.Error(). Str("channel_id", h.ChannelID). Str("connection_id", h.ConnectionID). Int32("code", status.GetCode()). - Msg(status.GetMessage()) + Msg(errMessage) + + err := fmt.Errorf(errMessage) + if err := encoder.Encode(NewSuzuErrorResponse(err)); err != nil { + zlog.Error(). + Err(err). + Str("channel_id", h.ChannelID). + Str("connection_id", h.ConnectionID). + Send() + } w.Close() return From b66a1aaabb70e4631a7dfacf90e447fd2012791d Mon Sep 17 00:00:00 2001 From: Yoshida Hiroshi Date: Tue, 13 Feb 2024 12:10:52 +0900 Subject: [PATCH 18/26] =?UTF-8?q?=E3=82=B3=E3=83=A1=E3=83=B3=E3=83=88?= =?UTF-8?q?=E3=82=92=E8=BF=BD=E5=8A=A0=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- amazon_transcribe_handler.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/amazon_transcribe_handler.go b/amazon_transcribe_handler.go index e23ee0f..5f07120 100644 --- a/amazon_transcribe_handler.go +++ b/amazon_transcribe_handler.go @@ -164,6 +164,7 @@ func (h *AmazonTranscribeHandler) Handle(ctx context.Context, reader io.Reader) err = ErrServerDisconnected default: + // 再接続を想定している以外のエラーの場合はクライアントにエラーを返し、再度接続するかはクライアント側で判断する if err := encoder.Encode(NewSuzuErrorResponse(err)); err != nil { zlog.Error(). Err(err). @@ -171,7 +172,6 @@ func (h *AmazonTranscribeHandler) Handle(ctx context.Context, reader io.Reader) Str("connection_id", h.ConnectionID). Send() } - } w.CloseWithError(err) From f168fb20780938af1962ab97843ac087cd5c246b Mon Sep 17 00:00:00 2001 From: Yoshida Hiroshi Date: Tue, 13 Feb 2024 12:12:21 +0900 Subject: [PATCH 19/26] =?UTF-8?q?=E5=86=8D=E6=8E=A5=E7=B6=9A=E6=9D=A1?= =?UTF-8?q?=E4=BB=B6=E3=82=92=20LimitExceededException=20=E3=81=AB?= =?UTF-8?q?=E7=B5=9E=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- amazon_transcribe_handler.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/amazon_transcribe_handler.go b/amazon_transcribe_handler.go index 5f07120..ac6d9a2 100644 --- a/amazon_transcribe_handler.go +++ b/amazon_transcribe_handler.go @@ -154,8 +154,7 @@ func (h *AmazonTranscribeHandler) Handle(ctx context.Context, reader io.Reader) if err := stream.Err(); err != nil { // 復帰が不可能なエラー以外は再接続を試みる switch err.(type) { - case *transcribestreamingservice.LimitExceededException, - *transcribestreamingservice.InternalFailureException: + case *transcribestreamingservice.LimitExceededException: zlog.Error(). Err(err). Str("channel_id", h.ChannelID). From 2a4f84d148f164adb4d8e8d86df9d95e0675765f Mon Sep 17 00:00:00 2001 From: Yoshida Hiroshi Date: Tue, 13 Feb 2024 13:19:57 +0900 Subject: [PATCH 20/26] =?UTF-8?q?=E3=83=86=E3=82=B9=E3=83=88=E3=82=92?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test_handler_test.go | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/test_handler_test.go b/test_handler_test.go index 05a33a0..57541ff 100644 --- a/test_handler_test.go +++ b/test_handler_test.go @@ -373,24 +373,32 @@ func TestSpeechHandler(t *testing.T) { c := e.NewContext(req, rec) h := s.createSpeechHandler(serviceType, func(ctx context.Context, w io.WriteCloser, chnanelID, connectionID, languageCode string, results any) error { - return fmt.Errorf("STREAM-ERROR") + go func() { + defer w.Close() + + encoder := json.NewEncoder(w) + if err := encoder.Encode(NewSuzuErrorResponse(fmt.Errorf("STREAM-ERROR"))); err != nil { + return + } + }() + + return nil }) err := h(c) - if assert.Error(t, err) { + if assert.NoError(t, err) { assert.Equal(t, http.StatusOK, rec.Code) delim := []byte("\n")[0] for { line, err := rec.Body.ReadBytes(delim) if err != nil { - if !assert.ErrorIs(t, err, io.EOF) { - t.Logf("STREAM-ERROR: %v\n", err) - } + assert.ErrorIs(t, err, io.EOF) break } + var result TranscriptionResult if err := json.Unmarshal(line, &result); err != nil { - t.Error(err) + assert.ErrorIs(t, err, io.EOF) } assert.Equal(t, "error", result.Type) From ee2556da75e1f19c996c6f00d467b1fe0c707f17 Mon Sep 17 00:00:00 2001 From: Yoshida Hiroshi Date: Tue, 13 Feb 2024 17:07:49 +0900 Subject: [PATCH 21/26] =?UTF-8?q?=E3=83=AA=E3=83=88=E3=83=A9=E3=82=A4?= =?UTF-8?q?=E3=81=8C=E7=84=A1=E5=8A=B9=E3=81=AB=E8=A8=AD=E5=AE=9A=E3=81=95?= =?UTF-8?q?=E3=82=8C=E3=81=A6=E3=81=84=E3=82=8B=E5=A0=B4=E5=90=88=E3=81=AF?= =?UTF-8?q?=E5=86=8D=E6=8E=A5=E7=B6=9A=E3=81=AE=E6=9D=A1=E4=BB=B6=E3=81=AB?= =?UTF-8?q?=E4=B8=80=E8=87=B4=E3=81=97=E3=81=A6=E3=82=82=E3=82=AF=E3=83=A9?= =?UTF-8?q?=E3=82=A4=E3=82=A2=E3=83=B3=E3=83=88=E3=81=AB=E3=82=A8=E3=83=A9?= =?UTF-8?q?=E3=83=BC=E3=82=92=E9=80=81=E4=BF=A1=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- amazon_transcribe_handler.go | 11 +++++++++++ speech_to_text_handler.go | 14 +++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/amazon_transcribe_handler.go b/amazon_transcribe_handler.go index ac6d9a2..6803f78 100644 --- a/amazon_transcribe_handler.go +++ b/amazon_transcribe_handler.go @@ -161,6 +161,17 @@ func (h *AmazonTranscribeHandler) Handle(ctx context.Context, reader io.Reader) Str("connection_id", h.ConnectionID). Send() + // リトライしない設定の場合はクライアントにエラーを返し、再度接続するかはクライアント側で判断する + if !*at.Config.Retry { + if err := encoder.Encode(NewSuzuErrorResponse(err)); err != nil { + zlog.Error(). + Err(err). + Str("channel_id", h.ChannelID). + Str("connection_id", h.ConnectionID). + Send() + } + } + err = ErrServerDisconnected default: // 再接続を想定している以外のエラーの場合はクライアントにエラーを返し、再度接続するかはクライアント側で判断する diff --git a/speech_to_text_handler.go b/speech_to_text_handler.go index e66bc9f..ce15e89 100644 --- a/speech_to_text_handler.go +++ b/speech_to_text_handler.go @@ -132,12 +132,24 @@ func (h *SpeechToTextHandler) Handle(ctx context.Context, reader io.Reader) (*io code == codes.InvalidArgument || code == codes.ResourceExhausted { + err := fmt.Errorf(status.GetMessage()) zlog.Error(). Err(err). Str("channel_id", h.ChannelID). Str("connection_id", h.ConnectionID). Int32("code", status.GetCode()). - Msg(status.GetMessage()) + Send() + + // リトライしない設定の場合はクライアントにエラーを返し、再度接続するかはクライアント側で判断する + if !*stt.Config.Retry { + if err := encoder.Encode(NewSuzuErrorResponse(err)); err != nil { + zlog.Error(). + Err(err). + Str("channel_id", h.ChannelID). + Str("connection_id", h.ConnectionID). + Send() + } + } w.CloseWithError(ErrServerDisconnected) return From 5828e846169ce243d68b119c830c4135d3799b52 Mon Sep 17 00:00:00 2001 From: Yoshida Hiroshi Date: Wed, 14 Feb 2024 16:25:17 +0900 Subject: [PATCH 22/26] =?UTF-8?q?=E3=82=B3=E3=82=B9=E3=83=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- amazon_transcribe_handler.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/amazon_transcribe_handler.go b/amazon_transcribe_handler.go index 6803f78..32214b2 100644 --- a/amazon_transcribe_handler.go +++ b/amazon_transcribe_handler.go @@ -3,6 +3,7 @@ package suzu import ( "context" "encoding/json" + "errors" "io" "github.com/aws/aws-sdk-go/service/transcribestreamingservice" @@ -73,7 +74,7 @@ func (h *AmazonTranscribeHandler) Handle(ctx context.Context, reader io.Reader) go func() { defer oggWriter.Close() if err := opus2ogg(ctx, reader, oggWriter, h.SampleRate, h.ChannelCount, h.Config); err != nil { - if err != io.EOF { + if !errors.Is(err, io.EOF) { zlog.Error(). Err(err). Str("channel_id", h.ChannelID). From 4de7c943a4aefc74156dd7e5abf5a75773b8d9dc Mon Sep 17 00:00:00 2001 From: Yoshida Hiroshi Date: Wed, 14 Feb 2024 16:46:11 +0900 Subject: [PATCH 23/26] =?UTF-8?q?EOF=20=E3=81=AF=E3=83=AD=E3=82=B0?= =?UTF-8?q?=E3=81=AB=E5=87=BA=E3=81=95=E3=81=AA=E3=81=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- speech_to_text_handler.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/speech_to_text_handler.go b/speech_to_text_handler.go index ce15e89..e49dea0 100644 --- a/speech_to_text_handler.go +++ b/speech_to_text_handler.go @@ -3,6 +3,7 @@ package suzu import ( "context" "encoding/json" + "errors" "fmt" "io" "strings" @@ -76,7 +77,7 @@ func (h *SpeechToTextHandler) Handle(ctx context.Context, reader io.Reader) (*io go func() { defer oggWriter.Close() if err := opus2ogg(ctx, reader, oggWriter, h.SampleRate, h.ChannelCount, h.Config); err != nil { - if err != io.EOF { + if !errors.Is(err, io.EOF) { zlog.Error(). Err(err). Str("channel_id", h.ChannelID). From bb892d4c73d95e3f2db5b2f68b2049738b392f92 Mon Sep 17 00:00:00 2001 From: Yoshida Hiroshi Date: Thu, 15 Feb 2024 11:09:04 +0900 Subject: [PATCH 24/26] =?UTF-8?q?=E3=82=B9=E3=83=88=E3=83=AA=E3=83=BC?= =?UTF-8?q?=E3=83=A0=E5=87=A6=E7=90=86=E5=89=8D=E3=81=AE=E3=82=A8=E3=83=A9?= =?UTF-8?q?=E3=83=BC=E3=82=92=20SuzuError=20=E3=81=AB=E5=A4=89=E6=9B=B4?= =?UTF-8?q?=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- speech_to_text.go | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/speech_to_text.go b/speech_to_text.go index 295e820..9700265 100644 --- a/speech_to_text.go +++ b/speech_to_text.go @@ -43,17 +43,26 @@ func (stt SpeechToText) Start(ctx context.Context, r io.Reader) (speechpb.Speech client, err := speech.NewClient(ctx, opts...) if err != nil { - return nil, err + return nil, &SuzuError{ + Code: 500, + Message: err.Error(), + } } stream, err := client.StreamingRecognize(ctx) if err != nil { - return nil, err + return nil, &SuzuError{ + Code: 500, + Message: err.Error(), + } } if err := stream.Send(&speechpb.StreamingRecognizeRequest{ StreamingRequest: streamingRecognitionConfig, }); err != nil { - return nil, err + return nil, &SuzuError{ + Code: 500, + Message: err.Error(), + } } go func() { From 6f26dcb349bc19f2ecfca9ac70c772f0fccc01ae Mon Sep 17 00:00:00 2001 From: Yoshida Hiroshi Date: Thu, 15 Feb 2024 11:18:59 +0900 Subject: [PATCH 25/26] =?UTF-8?q?=E5=A4=89=E6=9B=B4=E5=B1=A5=E6=AD=B4?= =?UTF-8?q?=E3=82=92=E6=9B=B4=E6=96=B0=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGES.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 55c1066..3609c21 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -11,6 +11,14 @@ ## develop +- [CHANGE] サービス接続時にエラーになった場合は、Body が空のレスポンスを返すように変更する + - @Hexa +- [CHANGE] サービス接続後にエラーになった場合は、{"type": "error", "reason": string} をクライアントへ送信するように変更する + - @Hexa +- [CHANGE] aws の再接続条件の exception から InternalFailureException を削除する + - @Hexa + + ## 2023.5.3 - [FIX] VERSION ファイルを tag のバージョンに修正する From 2174edf3a82b634441502bf2941720fafdc68ffa Mon Sep 17 00:00:00 2001 From: Yoshida Hiroshi Date: Thu, 15 Feb 2024 11:39:17 +0900 Subject: [PATCH 26/26] =?UTF-8?q?=E3=82=B3=E3=83=A1=E3=83=B3=E3=83=88?= =?UTF-8?q?=E3=82=92=E8=BF=BD=E5=8A=A0=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- speech_to_text.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/speech_to_text.go b/speech_to_text.go index 9700265..3dcafd6 100644 --- a/speech_to_text.go +++ b/speech_to_text.go @@ -44,6 +44,7 @@ func (stt SpeechToText) Start(ctx context.Context, r io.Reader) (speechpb.Speech client, err := speech.NewClient(ctx, opts...) if err != nil { return nil, &SuzuError{ + // TODO: 適切な StatusCode に変更する Code: 500, Message: err.Error(), } @@ -51,6 +52,7 @@ func (stt SpeechToText) Start(ctx context.Context, r io.Reader) (speechpb.Speech stream, err := client.StreamingRecognize(ctx) if err != nil { return nil, &SuzuError{ + // TODO: 適切な StatusCode に変更する Code: 500, Message: err.Error(), } @@ -60,6 +62,7 @@ func (stt SpeechToText) Start(ctx context.Context, r io.Reader) (speechpb.Speech StreamingRequest: streamingRecognitionConfig, }); err != nil { return nil, &SuzuError{ + // TODO: 適切な StatusCode に変更する Code: 500, Message: err.Error(), }