common errors as variable.

This commit is contained in:
Miroslav Šedivý 2021-08-29 17:09:13 +02:00
parent 530cc04805
commit 343b0c562a
17 changed files with 108 additions and 77 deletions

View File

@ -2,6 +2,7 @@ package members
import (
"context"
"errors"
"net/http"
"github.com/go-chi/chi"
@ -68,14 +69,21 @@ func GetMember(r *http.Request) MemberData {
func (h *MembersHandler) ExtractMember(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
memberId := chi.URLParam(r, "memberId")
profile, err := h.members.Select(memberId)
if err != nil {
if errors.Is(err, types.ErrMemberDoesNotExist) {
utils.HttpNotFound(w, err)
} else {
utils.HttpInternalServerError(w, err)
}
return
}
next.ServeHTTP(w, SetMember(r, MemberData{
ID: memberId,
Profile: profile,
}))
}
})
}

View File

@ -1,7 +1,6 @@
package capture
import (
"fmt"
"strings"
"sync"
@ -9,6 +8,7 @@ import (
"github.com/rs/zerolog/log"
"demodesk/neko/internal/capture/gst"
"demodesk/neko/internal/types"
)
type BroacastManagerCtx struct {
@ -67,7 +67,7 @@ func (manager *BroacastManagerCtx) Url() string {
func (manager *BroacastManagerCtx) createPipeline() error {
if manager.pipeline != nil {
return fmt.Errorf("pipeline already exists")
return types.ErrCapturePipelineAlreadyExists
}
var err error

View File

@ -1,7 +1,7 @@
package capture
import (
"fmt"
"errors"
"sync"
"sync/atomic"
"time"
@ -93,12 +93,12 @@ func (manager *ScreencastManagerCtx) Image() ([]byte, error) {
case sample := <-manager.sample:
return sample.Data, nil
case <-time.After(1 * time.Second):
return nil, fmt.Errorf("timeouted")
return nil, errors.New("timeouted")
}
}
if manager.image.Data == nil {
return nil, fmt.Errorf("image sample not found")
return nil, errors.New("image sample not found")
}
return manager.image.Data, nil
@ -109,7 +109,7 @@ func (manager *ScreencastManagerCtx) start() error {
defer manager.mu.Unlock()
if !manager.enabled {
return fmt.Errorf("screenshot pipeline not enabled")
return errors.New("screenshot pipeline not enabled")
}
err := manager.createPipeline()
@ -131,7 +131,7 @@ func (manager *ScreencastManagerCtx) stop() {
func (manager *ScreencastManagerCtx) createPipeline() error {
if manager.pipeline != nil {
return fmt.Errorf("pipeline already exists")
return types.ErrCapturePipelineAlreadyExists
}
var err error

View File

@ -1,7 +1,6 @@
package capture
import (
"fmt"
"reflect"
"sync"
@ -141,7 +140,7 @@ func (manager *StreamManagerCtx) Started() bool {
func (manager *StreamManagerCtx) createPipeline() error {
if manager.pipeline != nil {
return fmt.Errorf("pipeline already exists")
return types.ErrCapturePipelineAlreadyExists
}
var err error

View File

@ -1,7 +1,7 @@
package desktop
import (
"fmt"
"errors"
"os/exec"
"time"
)
@ -46,7 +46,7 @@ func (manager *DesktopManagerCtx) HandleFileChooserDialog(uri string) error {
// if last command didn't return error, consider dialog as still open
if err2 == nil {
return fmt.Errorf("unable to select files in dialog")
return errors.New("unable to select files in dialog")
}
return nil

View File

@ -1,7 +1,7 @@
package dummy
import (
"fmt"
"errors"
"demodesk/neko/internal/types"
)
@ -37,7 +37,7 @@ func (provider *MemberProviderCtx) Authenticate(username string, password string
}
func (provider *MemberProviderCtx) Insert(username string, password string, profile types.MemberProfile) (string, error) {
return "", fmt.Errorf("not implemented")
return "", errors.New("not implemented")
}
func (provider *MemberProviderCtx) Select(id string) (types.MemberProfile, error) {
@ -54,7 +54,7 @@ func (provider *MemberProviderCtx) UpdateProfile(id string, profile types.Member
}
func (provider *MemberProviderCtx) UpdatePassword(id string, password string) error {
return fmt.Errorf("not implemented")
return errors.New("not implemented")
}
func (provider *MemberProviderCtx) Delete(id string) error {

View File

@ -2,7 +2,6 @@ package file
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
@ -38,7 +37,7 @@ func (provider *MemberProviderCtx) Authenticate(username string, password string
// TODO: Use hash function.
if entry.Password != password {
return "", types.MemberProfile{}, fmt.Errorf("invalid password")
return "", types.MemberProfile{}, types.ErrMemberInvalidPassword
}
return id, entry.Profile, nil
@ -55,7 +54,7 @@ func (provider *MemberProviderCtx) Insert(username string, password string, prof
_, ok := entries[id]
if ok {
return "", fmt.Errorf("member ID already exists")
return "", types.ErrMemberAlreadyExists
}
entries[id] = MemberEntry{
@ -75,7 +74,7 @@ func (provider *MemberProviderCtx) UpdateProfile(id string, profile types.Member
entry, ok := entries[id]
if !ok {
return fmt.Errorf("member ID does not exist")
return types.ErrMemberDoesNotExist
}
entry.Profile = profile
@ -92,7 +91,7 @@ func (provider *MemberProviderCtx) UpdatePassword(id string, password string) er
entry, ok := entries[id]
if !ok {
return fmt.Errorf("member ID does not exist")
return types.ErrMemberDoesNotExist
}
// TODO: Use hash function.
@ -139,7 +138,7 @@ func (provider *MemberProviderCtx) Delete(id string) error {
_, ok := entries[id]
if !ok {
return fmt.Errorf("member ID does not exist")
return types.ErrMemberDoesNotExist
}
delete(entries, id)
@ -178,7 +177,7 @@ func (provider *MemberProviderCtx) getEntry(id string) (MemberEntry, error) {
entry, ok := entries[id]
if !ok {
return MemberEntry{}, fmt.Errorf("member ID does not exist")
return MemberEntry{}, types.ErrMemberDoesNotExist
}
return entry, nil

View File

@ -1,7 +1,7 @@
package member
import (
"fmt"
"errors"
"sync"
"github.com/rs/zerolog"
@ -41,7 +41,7 @@ type MemberManagerCtx struct {
config *config.Member
providerMu sync.Mutex
provider types.MemberProvider
sessionMu sync.Mutex
loginMu sync.Mutex
}
func (manager *MemberManagerCtx) Connect() error {
@ -91,13 +91,10 @@ func (manager *MemberManagerCtx) UpdateProfile(id string, profile types.MemberPr
defer manager.providerMu.Unlock()
// update corresponding session, if exists
manager.sessionMu.Lock()
if _, ok := manager.sessions.Get(id); ok {
if err := manager.sessions.Update(id, profile); err != nil {
err := manager.sessions.Update(id, profile)
if err != nil && !errors.Is(err, types.ErrSessionNotFound) {
manager.logger.Err(err).Msg("error while updating session")
}
}
manager.sessionMu.Unlock()
return manager.provider.UpdateProfile(id, profile)
}
@ -114,13 +111,10 @@ func (manager *MemberManagerCtx) Delete(id string) error {
defer manager.providerMu.Unlock()
// destroy corresponding session, if exists
manager.sessionMu.Lock()
if _, ok := manager.sessions.Get(id); ok {
if err := manager.sessions.Delete(id); err != nil {
err := manager.sessions.Delete(id)
if err != nil && !errors.Is(err, types.ErrSessionNotFound) {
manager.logger.Err(err).Msg("error while deleting session")
}
}
manager.sessionMu.Unlock()
return manager.provider.Delete(id)
}
@ -130,8 +124,8 @@ func (manager *MemberManagerCtx) Delete(id string) error {
//
func (manager *MemberManagerCtx) Login(username string, password string) (types.Session, string, error) {
manager.sessionMu.Lock()
defer manager.sessionMu.Unlock()
manager.loginMu.Lock()
defer manager.loginMu.Unlock()
id, profile, err := manager.provider.Authenticate(username, password)
if err != nil {
@ -141,7 +135,7 @@ func (manager *MemberManagerCtx) Login(username string, password string) (types.
session, ok := manager.sessions.Get(id)
if ok {
if session.State().IsConnected {
return nil, "", fmt.Errorf("session is already connected")
return nil, "", types.ErrSessionAlreadyConnected
}
// TODO: Replace session.
@ -154,12 +148,8 @@ func (manager *MemberManagerCtx) Login(username string, password string) (types.
}
func (manager *MemberManagerCtx) Logout(id string) error {
manager.sessionMu.Lock()
defer manager.sessionMu.Unlock()
if _, ok := manager.sessions.Get(id); !ok {
return fmt.Errorf("session not found")
}
manager.loginMu.Lock()
defer manager.loginMu.Unlock()
return manager.sessions.Delete(id)
}

View File

@ -1,8 +1,6 @@
package object
import (
"fmt"
"demodesk/neko/internal/types"
)
@ -60,12 +58,12 @@ func (provider *MemberProviderCtx) Authenticate(username string, password string
entry, ok := provider.entries[id]
if !ok {
return "", types.MemberProfile{}, fmt.Errorf("member ID does not exist")
return "", types.MemberProfile{}, types.ErrMemberDoesNotExist
}
// TODO: Use hash function.
if entry.Password != password {
return "", types.MemberProfile{}, fmt.Errorf("invalid password")
return "", types.MemberProfile{}, types.ErrMemberInvalidPassword
}
return id, entry.Profile, nil
@ -77,7 +75,7 @@ func (provider *MemberProviderCtx) Insert(username string, password string, prof
_, ok := provider.entries[id]
if ok {
return "", fmt.Errorf("member ID already exists")
return "", types.ErrMemberAlreadyExists
}
provider.entries[id] = &MemberEntry{
@ -92,7 +90,7 @@ func (provider *MemberProviderCtx) Insert(username string, password string, prof
func (provider *MemberProviderCtx) UpdateProfile(id string, profile types.MemberProfile) error {
entry, ok := provider.entries[id]
if !ok {
return fmt.Errorf("member ID does not exist")
return types.ErrMemberDoesNotExist
}
entry.Profile = profile
@ -103,7 +101,7 @@ func (provider *MemberProviderCtx) UpdateProfile(id string, profile types.Member
func (provider *MemberProviderCtx) UpdatePassword(id string, password string) error {
entry, ok := provider.entries[id]
if !ok {
return fmt.Errorf("member ID does not exist")
return types.ErrMemberDoesNotExist
}
// TODO: Use hash function.
@ -115,7 +113,7 @@ func (provider *MemberProviderCtx) UpdatePassword(id string, password string) er
func (provider *MemberProviderCtx) Select(id string) (types.MemberProfile, error) {
entry, ok := provider.entries[id]
if !ok {
return types.MemberProfile{}, fmt.Errorf("member ID does not exist")
return types.MemberProfile{}, types.ErrMemberDoesNotExist
}
return entry.Profile, nil
@ -139,7 +137,7 @@ func (provider *MemberProviderCtx) SelectAll(limit int, offset int) (map[string]
func (provider *MemberProviderCtx) Delete(id string) error {
_, ok := provider.entries[id]
if !ok {
return fmt.Errorf("member ID does not exist")
return types.ErrMemberDoesNotExist
}
delete(provider.entries, id)

View File

@ -1,7 +1,7 @@
package session
import (
"fmt"
"errors"
"net/http"
"strings"
"time"
@ -39,16 +39,16 @@ func (manager *SessionManagerCtx) CookieClearToken(w http.ResponseWriter, r *htt
func (manager *SessionManagerCtx) Authenticate(r *http.Request) (types.Session, error) {
token, ok := manager.getToken(r)
if !ok {
return nil, fmt.Errorf("no authentication provided")
return nil, errors.New("no authentication provided")
}
session, ok := manager.GetByToken(token)
if !ok {
return nil, fmt.Errorf("session not found")
return nil, types.ErrSessionNotFound
}
if !session.Profile().CanLogin {
return nil, fmt.Errorf("login disabled")
return nil, types.ErrSessionLoginDisabled
}
return session, nil

View File

@ -1,7 +1,7 @@
package session
import (
"fmt"
"errors"
"sync"
"github.com/kataras/go-events"
@ -68,12 +68,12 @@ func (manager *SessionManagerCtx) Create(id string, profile types.MemberProfile)
manager.sessionsMu.Lock()
if _, ok := manager.sessions[id]; ok {
manager.sessionsMu.Unlock()
return nil, "", fmt.Errorf("session id already exists")
return nil, "", types.ErrSessionAlreadyExists
}
if _, ok := manager.tokens[token]; ok {
manager.sessionsMu.Unlock()
return nil, "", fmt.Errorf("session token already exists")
return nil, "", errors.New("session token already exists")
}
session := &SessionCtx{
@ -98,7 +98,7 @@ func (manager *SessionManagerCtx) Update(id string, profile types.MemberProfile)
session, ok := manager.sessions[id]
if !ok {
manager.sessionsMu.Unlock()
return fmt.Errorf("session id not found")
return types.ErrSessionNotFound
}
session.profile = profile
@ -114,7 +114,7 @@ func (manager *SessionManagerCtx) Delete(id string) error {
session, ok := manager.sessions[id]
if !ok {
manager.sessionsMu.Unlock()
return fmt.Errorf("session id not found")
return types.ErrSessionNotFound
}
delete(manager.tokens, session.token)

View File

@ -2,6 +2,7 @@ package types
import (
"context"
"errors"
"fmt"
"math"
"strings"
@ -12,6 +13,10 @@ import (
"demodesk/neko/internal/types/codec"
)
var (
ErrCapturePipelineAlreadyExists = errors.New("capture pipeline already exists")
)
type Sample media.Sample
type BroadcastManager interface {

View File

@ -1,5 +1,13 @@
package types
import "errors"
var (
ErrMemberAlreadyExists = errors.New("member already exists")
ErrMemberDoesNotExist = errors.New("member does not exist")
ErrMemberInvalidPassword = errors.New("invalid password")
)
type MemberProfile struct {
Name string `json:"name"`
IsAdmin bool `json:"is_admin"`

View File

@ -1,6 +1,16 @@
package types
import "net/http"
import (
"errors"
"net/http"
)
var (
ErrSessionNotFound = errors.New("session not found")
ErrSessionAlreadyExists = errors.New("session already exists")
ErrSessionAlreadyConnected = errors.New("session is already connected")
ErrSessionLoginDisabled = errors.New("session login disabled")
)
type SessionState struct {
IsConnected bool `json:"is_connected"`

View File

@ -1,6 +1,15 @@
package types
import "github.com/pion/webrtc/v3"
import (
"errors"
"github.com/pion/webrtc/v3"
)
var (
ErrWebRTCVideoNotFound = errors.New("webrtc video not found")
ErrWebRTCDataChannelNotFound = errors.New("webrtc data channel not found")
)
type ICEServer struct {
URLs []string `mapstructure:"urls" json:"urls"`

View File

@ -66,7 +66,7 @@ func (manager *WebRTCManagerCtx) Start() {
}
audioListener := func(sample types.Sample) {
if err := manager.audioTrack.WriteSample(media.Sample(sample)); err != nil && err != io.ErrClosedPipe {
if err := manager.audioTrack.WriteSample(media.Sample(sample)); err != nil {
if errors.Is(err, io.ErrClosedPipe) {
// The peerConnection has been closed.
return
@ -166,7 +166,7 @@ func (manager *WebRTCManagerCtx) CreatePeer(session types.Session, videoID strin
}
videoListener := func(sample types.Sample) {
if err := videoTrack.WriteSample(media.Sample(sample)); err != nil && err != io.ErrClosedPipe {
if err := videoTrack.WriteSample(media.Sample(sample)); err != nil {
if errors.Is(err, io.ErrClosedPipe) {
// The peerConnection has been closed.
return
@ -200,7 +200,7 @@ func (manager *WebRTCManagerCtx) CreatePeer(session types.Session, videoID strin
changeVideo := func(videoID string) error {
newVideoStream, ok := manager.capture.Video(videoID)
if !ok {
return fmt.Errorf("video stream not found")
return types.ErrWebRTCVideoNotFound
}
// should be new stream started
@ -357,7 +357,7 @@ func (manager *WebRTCManagerCtx) mediaEngine(videoID string) (*webrtc.MediaEngin
// all videos must have the same codec
video, ok := manager.capture.Video(videoID)
if !ok {
return nil, fmt.Errorf("selected video track not found")
return nil, types.ErrWebRTCVideoNotFound
}
videoCodec := video.Codec()

View File

@ -3,7 +3,6 @@ package webrtc
import (
"bytes"
"encoding/binary"
"fmt"
"demodesk/neko/internal/types"
)
@ -28,8 +27,11 @@ type PayloadCursorImage struct {
}
func (peer *WebRTCPeerCtx) SendCursorPosition(x, y int) error {
peer.mu.Lock()
defer peer.mu.Unlock()
if peer.dataChannel == nil {
return fmt.Errorf("no data channel")
return types.ErrWebRTCDataChannelNotFound
}
data := PayloadCursorPosition{
@ -50,8 +52,11 @@ func (peer *WebRTCPeerCtx) SendCursorPosition(x, y int) error {
}
func (peer *WebRTCPeerCtx) SendCursorImage(cur *types.CursorImage, img []byte) error {
peer.mu.Lock()
defer peer.mu.Unlock()
if peer.dataChannel == nil {
return fmt.Errorf("no data channel")
return types.ErrWebRTCDataChannelNotFound
}
data := PayloadCursorImage{