mirror of
https://github.com/EnixCoda/Gitako.git
synced 2026-03-11 08:54:44 +00:00
refactor: more elegant init process, handle 409
GitHub API returns 409 if repo is created but empty
This commit is contained in:
parent
1208886efd
commit
b84bb18d1e
2 changed files with 61 additions and 36 deletions
|
|
@ -1,5 +1,10 @@
|
|||
import DOMHelper, { REPO_TYPE_PRIVATE } from 'utils/DOMHelper'
|
||||
import GitHubHelper, { NOT_FOUND, BAD_CREDENTIALS, API_RATE_LIMIT } from 'utils/GitHubHelper'
|
||||
import GitHubHelper, {
|
||||
NOT_FOUND,
|
||||
BAD_CREDENTIALS,
|
||||
API_RATE_LIMIT,
|
||||
EMPTY_PROJECT,
|
||||
} from 'utils/GitHubHelper'
|
||||
import configHelper from 'utils/configHelper'
|
||||
import URLHelper from 'utils/URLHelper'
|
||||
import keyHelper from 'utils/keyHelper'
|
||||
|
|
@ -8,35 +13,44 @@ const init = dispatch => async () => {
|
|||
try {
|
||||
if (!URLHelper.isInRepoPage()) return
|
||||
dispatch({ logoContainerElement: DOMHelper.insertLogoMountPoint() })
|
||||
let nothingWentWrong = true, branchDetected = false
|
||||
let detectedBranchName
|
||||
const metaData = URLHelper.parse()
|
||||
if (DOMHelper.isInCodePage()) {
|
||||
// in case GitHub page structure changes, fallback to 'master'
|
||||
let detectedBranchName = DOMHelper.getCurrentBranch()
|
||||
branchDetected = Boolean(detectedBranchName)
|
||||
detectedBranchName = detectedBranchName || 'master'
|
||||
metaData.branchName = detectedBranchName
|
||||
} else {
|
||||
metaData.branchName = 'master'
|
||||
branchDetected = false
|
||||
detectedBranchName = DOMHelper.getCurrentBranch()
|
||||
}
|
||||
metaData.branchName = detectedBranchName || 'master'
|
||||
dispatch(setMetaData, metaData)
|
||||
const { access_token: accessToken, shortcut, compressSingletonFolder, copyFileButton, copySnippetButton } = await configHelper.get()
|
||||
const {
|
||||
access_token: accessToken,
|
||||
shortcut,
|
||||
compressSingletonFolder,
|
||||
copyFileButton,
|
||||
copySnippetButton,
|
||||
} = await configHelper.get()
|
||||
DOMHelper.decorateGitHubPageContent({ copyFileButton, copySnippetButton })
|
||||
dispatch({ accessToken, toggleShowSideBarShortcut: shortcut, compressSingletonFolder, copyFileButton, copySnippetButton })
|
||||
dispatch({
|
||||
accessToken,
|
||||
toggleShowSideBarShortcut: shortcut,
|
||||
compressSingletonFolder,
|
||||
copyFileButton,
|
||||
copySnippetButton,
|
||||
})
|
||||
|
||||
const getTreeDataAggressively = GitHubHelper.getTreeData({
|
||||
...metaData,
|
||||
accessToken,
|
||||
}).catch(() => {
|
||||
})
|
||||
const caughtAggressiveError = getTreeDataAggressively.catch(error => {
|
||||
// 1. the repo has no master branch
|
||||
// 2. detect branch name from DOM failed
|
||||
// 3. not very possible...
|
||||
nothingWentWrong = false
|
||||
// not handle this error immediately
|
||||
return error
|
||||
})
|
||||
let getTreeData = getTreeDataAggressively
|
||||
const metaDataFromAPI = await GitHubHelper.getRepoMeta({ ...metaData, accessToken })
|
||||
const projectDefaultBranchName = metaDataFromAPI['default_branch']
|
||||
if (!branchDetected && projectDefaultBranchName !== metaData.branchName) {
|
||||
if (!detectedBranchName && projectDefaultBranchName !== metaData.branchName) {
|
||||
// Accessing repo's non-homepage(no branch name in URL, nor in DOM)
|
||||
// We predicted its default branch to be 'master' and sent aggressive request
|
||||
// Throw that request due to the repo do not use {defaultBranchName} as default branch
|
||||
|
|
@ -45,36 +59,37 @@ const init = dispatch => async () => {
|
|||
...metaData,
|
||||
accessToken,
|
||||
})
|
||||
} else {
|
||||
caughtAggressiveError.then(error => {
|
||||
// aggressive requested correct branch but ends in failure (e.g. project is empty)
|
||||
if (error instanceof Error) {
|
||||
dispatch(handleError, error)
|
||||
}
|
||||
})
|
||||
}
|
||||
getTreeData.then(treeData => dispatch({ treeData })).catch(err => dispatch(handleError, err))
|
||||
Object.assign(metaData, { api: metaDataFromAPI })
|
||||
dispatch(setMetaData, metaData)
|
||||
const shouldShow = URLHelper.isInCodePage(metaData)
|
||||
dispatch(setShouldShow, nothingWentWrong && shouldShow)
|
||||
getTreeData
|
||||
.then(treeData => {
|
||||
dispatch({ treeData })
|
||||
})
|
||||
.catch(err => {
|
||||
dispatch(handleError, err)
|
||||
})
|
||||
dispatch(setShouldShow, shouldShow)
|
||||
} catch (err) {
|
||||
dispatch(handleError, err)
|
||||
}
|
||||
}
|
||||
|
||||
const handleError = dispatch => async (err) => {
|
||||
const handleError = dispatch => async err => {
|
||||
// TODO: detect request time exceeds limit
|
||||
if (err.message === NOT_FOUND || err.message === BAD_CREDENTIALS || err.message === API_RATE_LIMIT ) {
|
||||
const repoPageType = await DOMHelper.getRepoPageType()
|
||||
const errorDueToAuth = repoPageType === REPO_TYPE_PRIVATE || err.message === BAD_CREDENTIALS || err.message === API_RATE_LIMIT
|
||||
dispatch({ errorDueToAuth })
|
||||
if (err.message === EMPTY_PROJECT) {
|
||||
dispatch(setError, 'This project seems to be empty.')
|
||||
} else if (
|
||||
err.message === NOT_FOUND ||
|
||||
err.message === BAD_CREDENTIALS ||
|
||||
err.message === API_RATE_LIMIT
|
||||
) {
|
||||
dispatch({ errorDueToAuth: true })
|
||||
dispatch(setShowSettings, true)
|
||||
dispatch(setShouldShow, errorDueToAuth)
|
||||
if (!errorDueToAuth) {
|
||||
dispatch(setError, 'Gitako ate a bug, but it should recovery soon!')
|
||||
}
|
||||
dispatch(setShouldShow, true)
|
||||
} else {
|
||||
dispatch(setShouldShow, false)
|
||||
dispatch(setError, 'Gitako ate a bug, but it should recovery soon!')
|
||||
}
|
||||
}
|
||||
|
|
@ -100,7 +115,8 @@ const onKeyDown = dispatch => e => {
|
|||
})
|
||||
}
|
||||
|
||||
const toggleShowSideBar = dispatch => () => dispatch(({ shouldShow }) => dispatch(setShouldShow, !shouldShow))
|
||||
const toggleShowSideBar = dispatch => () =>
|
||||
dispatch(({ shouldShow }) => dispatch(setShouldShow, !shouldShow))
|
||||
|
||||
const setShouldShow = dispatch => shouldShow => {
|
||||
dispatch({ shouldShow }, shouldShow ? DOMHelper.focusFileExplorer : null)
|
||||
|
|
@ -109,9 +125,11 @@ const setShouldShow = dispatch => shouldShow => {
|
|||
|
||||
const setError = dispatch => error => {
|
||||
dispatch({ error })
|
||||
dispatch(setShouldShow, false)
|
||||
}
|
||||
|
||||
const toggleShowSettings = dispatch => () => dispatch(({ showSettings }) => ({ showSettings: !showSettings }))
|
||||
const toggleShowSettings = dispatch => () =>
|
||||
dispatch(({ showSettings }) => ({ showSettings: !showSettings }))
|
||||
|
||||
const setShowSettings = dispatch => showSettings => dispatch({ showSettings })
|
||||
|
||||
|
|
@ -121,7 +139,8 @@ const onShortcutChange = dispatch => shortcut => dispatch({ toggleShowSideBarSho
|
|||
|
||||
const setMetaData = dispatch => metaData => dispatch({ metaData })
|
||||
|
||||
const setCompressSingleton = dispatch => compressSingletonFolder => dispatch({ compressSingletonFolder })
|
||||
const setCompressSingleton = dispatch => compressSingletonFolder =>
|
||||
dispatch({ compressSingletonFolder })
|
||||
|
||||
const setCopyFile = dispatch => copyFileButton => dispatch({ copyFileButton })
|
||||
|
||||
|
|
|
|||
|
|
@ -2,11 +2,16 @@ import { raiseError } from 'analytics'
|
|||
export const NOT_FOUND = 'Repo Not Found'
|
||||
export const BAD_CREDENTIALS = 'Bad credentials'
|
||||
export const API_RATE_LIMIT = `API rate limit`
|
||||
export const EMPTY_PROJECT = `Empty project`
|
||||
|
||||
function apiRateLimitExceeded(content) {
|
||||
return content && content['documentation_url'] === 'https://developer.github.com/v3/#rate-limiting'
|
||||
}
|
||||
|
||||
function isEmptyProject(content) {
|
||||
return content && content['message'] === 'Git Repository is empty.'
|
||||
}
|
||||
|
||||
async function request(url, { accessToken } = {}) {
|
||||
const headers = {}
|
||||
if (accessToken) {
|
||||
|
|
@ -19,6 +24,7 @@ async function request(url, { accessToken } = {}) {
|
|||
else {
|
||||
const content = await res.json()
|
||||
if (apiRateLimitExceeded(content)) throw new Error(API_RATE_LIMIT)
|
||||
else if (isEmptyProject(content)) throw new Error(EMPTY_PROJECT)
|
||||
else if (!res.ok) raiseError(new Error(`Got ${res.statusText} when requesting ${url}`))
|
||||
throw new Error(content && content.message)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue