Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
D
dify
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ai-tech
dify
Commits
9a5ae9f5
Unverified
Commit
9a5ae9f5
authored
May 22, 2023
by
John Wang
Committed by
GitHub
May 22, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Feat: optimize error desc (#152)
parent
a7c40a07
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
119 additions
and
55 deletions
+119
-55
__init__.py
api/controllers/console/app/__init__.py
+1
-1
error.py
api/controllers/console/app/error.py
+8
-6
datasets_document.py
api/controllers/console/datasets/datasets_document.py
+11
-2
error.py
api/controllers/console/datasets/error.py
+8
-8
hit_testing.py
api/controllers/console/datasets/hit_testing.py
+9
-0
error.py
api/controllers/console/error.py
+3
-2
error.py
api/controllers/console/workspace/error.py
+2
-2
providers.py
api/controllers/console/workspace/providers.py
+2
-2
error.py
api/controllers/service_api/app/error.py
+9
-7
error.py
api/controllers/service_api/dataset/error.py
+1
-1
error.py
api/controllers/web/error.py
+11
-9
index_builder.py
api/core/index/index_builder.py
+12
-0
vector_index.py
api/core/index/vector_index.py
+2
-2
azure_provider.py
api/core/llm/provider/azure_provider.py
+39
-12
common.en.ts
web/i18n/lang/common.en.ts
+1
-1
No files found.
api/controllers/console/app/__init__.py
View file @
9a5ae9f5
...
...
@@ -17,6 +17,6 @@ def _get_app(app_id, mode=None):
raise
NotFound
(
"App not found"
)
if
mode
and
app
.
mode
!=
mode
:
raise
AppUnavailableError
(
)
raise
NotFound
(
"The {} app not found"
.
format
(
mode
)
)
return
app
api/controllers/console/app/error.py
View file @
9a5ae9f5
...
...
@@ -9,31 +9,33 @@ class AppNotFoundError(BaseHTTPException):
class
ProviderNotInitializeError
(
BaseHTTPException
):
error_code
=
'provider_not_initialize'
description
=
"Provider Token not initialize."
description
=
"No valid model provider credentials found. "
\
"Please go to Settings -> Model Provider to complete your provider credentials."
code
=
400
class
ProviderQuotaExceededError
(
BaseHTTPException
):
error_code
=
'provider_quota_exceeded'
description
=
"Provider quota exceeded."
description
=
"Your quota for Dify Hosted OpenAI has been exhausted. "
\
"Please go to Settings -> Model Provider to complete your own provider credentials."
code
=
400
class
ProviderModelCurrentlyNotSupportError
(
BaseHTTPException
):
error_code
=
'model_currently_not_support'
description
=
"
GPT-4 currently not support
."
description
=
"
Dify Hosted OpenAI trial currently not support the GPT-4 model
."
code
=
400
class
ConversationCompletedError
(
BaseHTTPException
):
error_code
=
'conversation_completed'
description
=
"
Conversation was completed
."
description
=
"
The conversation has ended. Please start a new conversation
."
code
=
400
class
AppUnavailableError
(
BaseHTTPException
):
error_code
=
'app_unavailable'
description
=
"App unavailable."
description
=
"App unavailable
, please check your app configurations
."
code
=
400
...
...
@@ -45,5 +47,5 @@ class CompletionRequestError(BaseHTTPException):
class
AppMoreLikeThisDisabledError
(
BaseHTTPException
):
error_code
=
'app_more_like_this_disabled'
description
=
"
More like this disabled
."
description
=
"
The 'More like this' feature is disabled. Please refresh your page
."
code
=
403
api/controllers/console/datasets/datasets_document.py
View file @
9a5ae9f5
...
...
@@ -10,13 +10,14 @@ from werkzeug.exceptions import NotFound, Forbidden
import
services
from
controllers.console
import
api
from
controllers.console.app.error
import
ProviderNotInitializeError
from
controllers.console.app.error
import
ProviderNotInitializeError
,
ProviderQuotaExceededError
,
\
ProviderModelCurrentlyNotSupportError
from
controllers.console.datasets.error
import
DocumentAlreadyFinishedError
,
InvalidActionError
,
DocumentIndexingError
,
\
InvalidMetadataError
,
ArchivedDocumentImmutableError
from
controllers.console.setup
import
setup_required
from
controllers.console.wraps
import
account_initialization_required
from
core.indexing_runner
import
IndexingRunner
from
core.llm.error
import
ProviderTokenNotInitError
from
core.llm.error
import
ProviderTokenNotInitError
,
QuotaExceededError
,
ModelCurrentlyNotSupportError
from
extensions.ext_redis
import
redis_client
from
libs.helper
import
TimestampField
from
extensions.ext_database
import
db
...
...
@@ -222,6 +223,10 @@ class DatasetDocumentListApi(Resource):
document
=
DocumentService
.
save_document_with_dataset_id
(
dataset
,
args
,
current_user
)
except
ProviderTokenNotInitError
:
raise
ProviderNotInitializeError
()
except
QuotaExceededError
:
raise
ProviderQuotaExceededError
()
except
ModelCurrentlyNotSupportError
:
raise
ProviderModelCurrentlyNotSupportError
()
return
document
...
...
@@ -259,6 +264,10 @@ class DatasetInitApi(Resource):
)
except
ProviderTokenNotInitError
:
raise
ProviderNotInitializeError
()
except
QuotaExceededError
:
raise
ProviderQuotaExceededError
()
except
ModelCurrentlyNotSupportError
:
raise
ProviderModelCurrentlyNotSupportError
()
response
=
{
'dataset'
:
dataset
,
...
...
api/controllers/console/datasets/error.py
View file @
9a5ae9f5
...
...
@@ -3,7 +3,7 @@ from libs.exception import BaseHTTPException
class
NoFileUploadedError
(
BaseHTTPException
):
error_code
=
'no_file_uploaded'
description
=
"
No file uploaded
."
description
=
"
Please upload your file
."
code
=
400
...
...
@@ -27,25 +27,25 @@ class UnsupportedFileTypeError(BaseHTTPException):
class
HighQualityDatasetOnlyError
(
BaseHTTPException
):
error_code
=
'high_quality_dataset_only'
description
=
"
High quality dataset only
."
description
=
"
Current operation only supports 'high-quality' datasets
."
code
=
400
class
DatasetNotInitializedError
(
BaseHTTPException
):
error_code
=
'dataset_not_initialized'
description
=
"
Dataset not initialized
."
description
=
"
The dataset is still being initialized or indexing. Please wait a moment
."
code
=
400
class
ArchivedDocumentImmutableError
(
BaseHTTPException
):
error_code
=
'archived_document_immutable'
description
=
"
Cannot process an archived document
."
description
=
"
The archived document is not editable
."
code
=
403
class
DatasetNameDuplicateError
(
BaseHTTPException
):
error_code
=
'dataset_name_duplicate'
description
=
"
Dataset name already exists
."
description
=
"
The dataset name already exists. Please modify your dataset name
."
code
=
409
...
...
@@ -57,17 +57,17 @@ class InvalidActionError(BaseHTTPException):
class
DocumentAlreadyFinishedError
(
BaseHTTPException
):
error_code
=
'document_already_finished'
description
=
"
Document already finished
."
description
=
"
The document has been processed. Please refresh the page or go to the document details
."
code
=
400
class
DocumentIndexingError
(
BaseHTTPException
):
error_code
=
'document_indexing'
description
=
"
Document indexing
."
description
=
"
The document is being processed and cannot be edited
."
code
=
400
class
InvalidMetadataError
(
BaseHTTPException
):
error_code
=
'invalid_metadata'
description
=
"
Invalid metadata
."
description
=
"
The metadata content is incorrect. Please check and verify
."
code
=
400
api/controllers/console/datasets/hit_testing.py
View file @
9a5ae9f5
...
...
@@ -6,9 +6,12 @@ from werkzeug.exceptions import InternalServerError, NotFound, Forbidden
import
services
from
controllers.console
import
api
from
controllers.console.app.error
import
ProviderNotInitializeError
,
ProviderQuotaExceededError
,
\
ProviderModelCurrentlyNotSupportError
from
controllers.console.datasets.error
import
HighQualityDatasetOnlyError
,
DatasetNotInitializedError
from
controllers.console.setup
import
setup_required
from
controllers.console.wraps
import
account_initialization_required
from
core.llm.error
import
ProviderTokenNotInitError
,
QuotaExceededError
,
ModelCurrentlyNotSupportError
from
libs.helper
import
TimestampField
from
services.dataset_service
import
DatasetService
from
services.hit_testing_service
import
HitTestingService
...
...
@@ -92,6 +95,12 @@ class HitTestingApi(Resource):
return
{
"query"
:
response
[
'query'
],
'records'
:
marshal
(
response
[
'records'
],
hit_testing_record_fields
)}
except
services
.
errors
.
index
.
IndexNotInitializedError
:
raise
DatasetNotInitializedError
()
except
ProviderTokenNotInitError
:
raise
ProviderNotInitializeError
()
except
QuotaExceededError
:
raise
ProviderQuotaExceededError
()
except
ModelCurrentlyNotSupportError
:
raise
ProviderModelCurrentlyNotSupportError
()
except
Exception
as
e
:
logging
.
exception
(
"Hit testing failed."
)
raise
InternalServerError
(
str
(
e
))
...
...
api/controllers/console/error.py
View file @
9a5ae9f5
...
...
@@ -3,13 +3,14 @@ from libs.exception import BaseHTTPException
class
AlreadySetupError
(
BaseHTTPException
):
error_code
=
'already_setup'
description
=
"
Application already setup
."
description
=
"
Dify has been successfully installed. Please refresh the page or return to the dashboard homepage
."
code
=
403
class
NotSetupError
(
BaseHTTPException
):
error_code
=
'not_setup'
description
=
"Application not setup."
description
=
"Dify has not been initialized and installed yet. "
\
"Please proceed with the initialization and installation process first."
code
=
401
...
...
api/controllers/console/workspace/error.py
View file @
9a5ae9f5
...
...
@@ -21,11 +21,11 @@ class InvalidInvitationCodeError(BaseHTTPException):
class
AccountAlreadyInitedError
(
BaseHTTPException
):
error_code
=
'account_already_inited'
description
=
"
Account already inited
."
description
=
"
The account has been initialized. Please refresh the page
."
code
=
400
class
AccountNotInitializedError
(
BaseHTTPException
):
error_code
=
'account_not_initialized'
description
=
"
Account not initialized
."
description
=
"
The account has not been initialized yet. Please proceed with the initialization process first
."
code
=
400
api/controllers/console/workspace/providers.py
View file @
9a5ae9f5
...
...
@@ -90,8 +90,8 @@ class ProviderTokenApi(Resource):
configs
=
args
[
'token'
]
)
token_is_valid
=
True
except
ValidateFailedError
:
token_is_valid
=
False
except
ValidateFailedError
as
ex
:
raise
ValueError
(
str
(
ex
))
base64_encrypted_token
=
ProviderService
.
get_encrypted_token
(
tenant
=
current_user
.
current_tenant
,
...
...
api/controllers/service_api/app/error.py
View file @
9a5ae9f5
...
...
@@ -4,43 +4,45 @@ from libs.exception import BaseHTTPException
class
AppUnavailableError
(
BaseHTTPException
):
error_code
=
'app_unavailable'
description
=
"App unavailable."
description
=
"App unavailable
, please check your app configurations
."
code
=
400
class
NotCompletionAppError
(
BaseHTTPException
):
error_code
=
'not_completion_app'
description
=
"
Not Completion App
"
description
=
"
Please check if your Completion app mode matches the right API route.
"
code
=
400
class
NotChatAppError
(
BaseHTTPException
):
error_code
=
'not_chat_app'
description
=
"
Not Chat App
"
description
=
"
Please check if your Chat app mode matches the right API route.
"
code
=
400
class
ConversationCompletedError
(
BaseHTTPException
):
error_code
=
'conversation_completed'
description
=
"
Conversation Completed
."
description
=
"
The conversation has ended. Please start a new conversation
."
code
=
400
class
ProviderNotInitializeError
(
BaseHTTPException
):
error_code
=
'provider_not_initialize'
description
=
"Provider Token not initialize."
description
=
"No valid model provider credentials found. "
\
"Please go to Settings -> Model Provider to complete your provider credentials."
code
=
400
class
ProviderQuotaExceededError
(
BaseHTTPException
):
error_code
=
'provider_quota_exceeded'
description
=
"Provider quota exceeded."
description
=
"Your quota for Dify Hosted OpenAI has been exhausted. "
\
"Please go to Settings -> Model Provider to complete your own provider credentials."
code
=
400
class
ProviderModelCurrentlyNotSupportError
(
BaseHTTPException
):
error_code
=
'model_currently_not_support'
description
=
"
GPT-4 currently not support
."
description
=
"
Dify Hosted OpenAI trial currently not support the GPT-4 model
."
code
=
400
...
...
api/controllers/service_api/dataset/error.py
View file @
9a5ae9f5
...
...
@@ -16,5 +16,5 @@ class DocumentIndexingError(BaseHTTPException):
class
DatasetNotInitedError
(
BaseHTTPException
):
error_code
=
'dataset_not_inited'
description
=
"
Dataset not inited
."
description
=
"
The dataset is still being initialized or indexing. Please wait a moment
."
code
=
403
api/controllers/web/error.py
View file @
9a5ae9f5
...
...
@@ -4,43 +4,45 @@ from libs.exception import BaseHTTPException
class
AppUnavailableError
(
BaseHTTPException
):
error_code
=
'app_unavailable'
description
=
"App unavailable."
description
=
"App unavailable
, please check your app configurations
."
code
=
400
class
NotCompletionAppError
(
BaseHTTPException
):
error_code
=
'not_completion_app'
description
=
"
Not Completion App
"
description
=
"
Please check if your Completion app mode matches the right API route.
"
code
=
400
class
NotChatAppError
(
BaseHTTPException
):
error_code
=
'not_chat_app'
description
=
"
Not Chat App
"
description
=
"
Please check if your Chat app mode matches the right API route.
"
code
=
400
class
ConversationCompletedError
(
BaseHTTPException
):
error_code
=
'conversation_completed'
description
=
"
Conversation Completed
."
description
=
"
The conversation has ended. Please start a new conversation
."
code
=
400
class
ProviderNotInitializeError
(
BaseHTTPException
):
error_code
=
'provider_not_initialize'
description
=
"Provider Token not initialize."
description
=
"No valid model provider credentials found. "
\
"Please go to Settings -> Model Provider to complete your provider credentials."
code
=
400
class
ProviderQuotaExceededError
(
BaseHTTPException
):
error_code
=
'provider_quota_exceeded'
description
=
"Provider quota exceeded."
description
=
"Your quota for Dify Hosted OpenAI has been exhausted. "
\
"Please go to Settings -> Model Provider to complete your own provider credentials."
code
=
400
class
ProviderModelCurrentlyNotSupportError
(
BaseHTTPException
):
error_code
=
'model_currently_not_support'
description
=
"
GPT-4 currently not support
."
description
=
"
Dify Hosted OpenAI trial currently not support the GPT-4 model
."
code
=
400
...
...
@@ -52,11 +54,11 @@ class CompletionRequestError(BaseHTTPException):
class
AppMoreLikeThisDisabledError
(
BaseHTTPException
):
error_code
=
'app_more_like_this_disabled'
description
=
"
More like this disabled
."
description
=
"
The 'More like this' feature is disabled. Please refresh your page
."
code
=
403
class
AppSuggestedQuestionsAfterAnswerDisabledError
(
BaseHTTPException
):
error_code
=
'app_suggested_questions_after_answer_disabled'
description
=
"
Function Suggested questions after answer disabled
."
description
=
"
The 'Suggested Questions After Answer' feature is disabled. Please refresh your page
."
code
=
403
api/core/index/index_builder.py
View file @
9a5ae9f5
...
...
@@ -46,3 +46,15 @@ class IndexBuilder:
prompt_helper
=
prompt_helper
,
embed_model
=
OpenAIEmbedding
(
**
model_credentials
),
)
@
classmethod
def
get_fake_llm_service_context
(
cls
,
tenant_id
:
str
)
->
ServiceContext
:
llm
=
LLMBuilder
.
to_llm
(
tenant_id
=
tenant_id
,
model_name
=
'fake'
)
return
ServiceContext
.
from_defaults
(
llm_predictor
=
LLMPredictor
(
llm
=
llm
),
embed_model
=
OpenAIEmbedding
()
)
api/core/index/vector_index.py
View file @
9a5ae9f5
...
...
@@ -83,7 +83,7 @@ class VectorIndex:
if
not
self
.
_dataset
.
index_struct_dict
:
return
service_context
=
IndexBuilder
.
get_
default
_service_context
(
tenant_id
=
self
.
_dataset
.
tenant_id
)
service_context
=
IndexBuilder
.
get_
fake_llm
_service_context
(
tenant_id
=
self
.
_dataset
.
tenant_id
)
index
=
vector_store
.
get_index
(
service_context
=
service_context
,
...
...
@@ -101,7 +101,7 @@ class VectorIndex:
if
not
self
.
_dataset
.
index_struct_dict
:
return
service_context
=
IndexBuilder
.
get_
default
_service_context
(
tenant_id
=
self
.
_dataset
.
tenant_id
)
service_context
=
IndexBuilder
.
get_
fake_llm
_service_context
(
tenant_id
=
self
.
_dataset
.
tenant_id
)
index
=
vector_store
.
get_index
(
service_context
=
service_context
,
...
...
api/core/llm/provider/azure_provider.py
View file @
9a5ae9f5
import
json
import
logging
from
typing
import
Optional
,
Union
import
requests
from
core.llm.provider.base
import
BaseProvider
from
core.llm.provider.errors
import
ValidateFailedError
from
models.provider
import
ProviderName
class
AzureProvider
(
BaseProvider
):
def
get_models
(
self
,
model_id
:
Optional
[
str
]
=
None
)
->
list
[
dict
]:
credentials
=
self
.
get_credentials
(
model_id
)
def
get_models
(
self
,
model_id
:
Optional
[
str
]
=
None
,
credentials
:
Optional
[
dict
]
=
None
)
->
list
[
dict
]:
credentials
=
self
.
get_credentials
(
model_id
)
if
not
credentials
else
credentials
url
=
"{}/openai/deployments?api-version={}"
.
format
(
credentials
.
get
(
'openai_api_base'
),
credentials
.
get
(
'openai_api_version'
)
str
(
credentials
.
get
(
'openai_api_base'
)
),
str
(
credentials
.
get
(
'openai_api_version'
)
)
)
headers
=
{
"api-key"
:
credentials
.
get
(
'openai_api_key'
),
"api-key"
:
str
(
credentials
.
get
(
'openai_api_key'
)
),
"content-type"
:
"application/json; charset=utf-8"
}
...
...
@@ -29,8 +31,10 @@ class AzureProvider(BaseProvider):
'name'
:
'{} ({})'
.
format
(
deployment
[
'id'
],
deployment
[
'model'
])
}
for
deployment
in
result
[
'data'
]
if
deployment
[
'status'
]
==
'succeeded'
]
else
:
# TODO: optimize in future
raise
Exception
(
'Failed to get deployments from Azure OpenAI. Status code: {}'
.
format
(
response
.
status_code
))
if
response
.
status_code
==
401
:
raise
AzureAuthenticationError
()
else
:
raise
AzureRequestFailedError
(
'Failed to request Azure OpenAI. Status code: {}'
.
format
(
response
.
status_code
))
def
get_credentials
(
self
,
model_id
:
Optional
[
str
]
=
None
)
->
dict
:
"""
...
...
@@ -38,7 +42,7 @@ class AzureProvider(BaseProvider):
"""
config
=
self
.
get_provider_api_key
(
model_id
=
model_id
)
config
[
'openai_api_type'
]
=
'azure'
config
[
'deployment_name'
]
=
model_id
.
replace
(
'.'
,
''
)
config
[
'deployment_name'
]
=
model_id
.
replace
(
'.'
,
''
)
if
model_id
else
None
return
config
def
get_provider_name
(
self
):
...
...
@@ -54,7 +58,7 @@ class AzureProvider(BaseProvider):
config
=
{
'openai_api_type'
:
'azure'
,
'openai_api_version'
:
'2023-03-15-preview'
,
'openai_api_base'
:
'
https://<your-domain-prefix>.openai.azure.com/
'
,
'openai_api_base'
:
''
,
'openai_api_key'
:
''
}
...
...
@@ -63,7 +67,7 @@ class AzureProvider(BaseProvider):
config
=
{
'openai_api_type'
:
'azure'
,
'openai_api_version'
:
'2023-03-15-preview'
,
'openai_api_base'
:
'
https://<your-domain-prefix>.openai.azure.com/
'
,
'openai_api_base'
:
''
,
'openai_api_key'
:
''
}
...
...
@@ -80,8 +84,23 @@ class AzureProvider(BaseProvider):
"""
Validates the given config.
"""
# TODO: implement
pass
try
:
if
not
isinstance
(
config
,
dict
):
raise
ValueError
(
'Config must be a object.'
)
if
'openai_api_version'
not
in
config
:
config
[
'openai_api_version'
]
=
'2023-03-15-preview'
self
.
get_models
(
credentials
=
config
)
except
AzureAuthenticationError
:
raise
ValidateFailedError
(
'Azure OpenAI Credentials validation failed, please check your API Key.'
)
except
requests
.
ConnectionError
:
raise
ValidateFailedError
(
'Azure OpenAI Credentials validation failed, please check your API Base Endpoint.'
)
except
AzureRequestFailedError
as
ex
:
raise
ValidateFailedError
(
'Azure OpenAI Credentials validation failed, error: {}.'
.
format
(
str
(
ex
)))
except
Exception
as
ex
:
logging
.
exception
(
'Azure OpenAI Credentials validation failed'
)
raise
ex
def
get_encrypted_token
(
self
,
config
:
Union
[
dict
|
str
]):
"""
...
...
@@ -101,3 +120,11 @@ class AzureProvider(BaseProvider):
config
=
json
.
loads
(
token
)
config
[
'openai_api_key'
]
=
self
.
decrypt_token
(
config
[
'openai_api_key'
])
return
config
class
AzureAuthenticationError
(
Exception
):
pass
class
AzureRequestFailedError
(
Exception
):
pass
web/i18n/lang/common.en.ts
View file @
9a5ae9f5
...
...
@@ -149,7 +149,7 @@ const translation = {
invalidApiKey
:
'Invalid API key'
,
azure
:
{
apiBase
:
'API Base'
,
apiBasePlaceholder
:
'The API Base URL of your Azure OpenAI
Resource
.'
,
apiBasePlaceholder
:
'The API Base URL of your Azure OpenAI
Endpoint
.'
,
apiKey
:
'API Key'
,
apiKeyPlaceholder
:
'Enter your API key here'
,
helpTip
:
'Learn Azure OpenAI Service'
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment